Question:
Introductory:
There is an sms
table that contains data about the pending sms. There is also a text_patterns
table that stores text patterns prepared by the user. The sms
table has a pattern_id
field – a link to a text template
The user uploads a csv file to the system. In the csv file there is a list to which number which text template to send. 2 columns. Number, template id.
Now all this is processed and working
Task:
We want to add a feature so that in the second column you can write not only an existing text template, but also the text itself to be sent. Those. I will look at what is in this field – if it is a number, then this is a text template, and if it is a string, then some new processing logic.
I can't figure out how to store this data in the database.
Solution options:
-
If text, then create a new text pattern in the
text_patterns
table and continue to work according to the old scheme. I don't like the solution, because templates can be very unique and each number will have its own separate template. The template logic is missing. -
Add a text field to the
sms
table in which to store the value. those. add thesms_text
field and the link to the test patternis_pattern
(0|1). I don't like the solution. we will have empty fields on each line, eitherpattern_id
orsms_text
. Also, for further data processing, I will need to write 2 queries all the time instead of one. One for sms with templates, the other for sms with custom text.
Maybe there are some more beautiful solutions?
Answer:
Your second option is similar to the truth, only it needs to be completed a little. We need two fields: template id and template text, both fields allow NULL values. template-id must be a foraign key pointing to the table with templates. Do not be afraid of NULL values, the DBMS does not actually store them, for example, MySQL stores one bit in the record header for such fields, indicating whether the field exists or not, other DBMSs act in much the same way. There is no need for any indication of whether there is a "unique template" in the record, the very fact of the presence of text in the sms_text
field is a sign. At the trigger level, you can prevent the insertion of records where both fields are filled or none of them are filled.
Also, to get the current template, two requests are not needed, everything is solved with one request:
select ..., coalesce(T.text,S.sms_text)
from sms S
left join text_patterns T on T.id=S.pattern_id
We join tables by LEFT JOIN
, so if the pattern_id
field is empty, then the query will still return the record, only in it the text from the template table will be NULL. The coalesce()
function will return the first of the listed fields that is NOT NULL, i.e. if the template id is set and an entry in the templates is found, then the text will be taken from there, if the template is not set, then the text will be taken from the sms_text field in the sms table entry itself. Perhaps it is worth rearranging the arguments, then the text from the sms itself will take precedence over that found in the templates if both fields are filled.