D
D
dblearn942019-12-17 11:44:02
SQL
dblearn94, 2019-12-17 11:44:02

Redundant data or complex query logic?

Hello, there are 2 tables, I will simplify for example:
1. setting:
id | name
2. setting_value:
id | setting_id | domain_id | language_id | value
domain_id (if null - then the setting is common for all sites)
language_id (if null - then the setting is for all languages) It is
necessary that for each domain and language there should be setting, and if it was not filled, then "standard" was returned.
And here is the problem and the big question, how best to do it:
1 (as it is done now):
I get a difficult question in my opinion, with the following logic:

Получаем данные для текущего домена (32) и языка (15).
UNION
Получаем данные для текущего домена (32) стандартного языка (1), исключая setting_id полученные из прошлого запроса.
UNION
Получаем данные для текущего домена (32) и общего языка (null), исключая прошлые запросы
UNION
Получаем данные для стандартного домена (1) и текущего языка (15), исключая прошлые запросы

И т.д пока не переберем все варианты

2. Just spawn copies so that for each language, each setting there is a record and get it according to the current parameters with a request:
SELECT * FROM `setting_value` WHERE `domain_id` = 32 AND `language_id` = 15

But the data will grow exponentially.
for example:
20 settings for 100 subdomains + 10 languages ​​= 2000 entries in setting_value, most of which will be copies
But here's the thing, on the scales:
  1. Complex query consisting of 9 combined queries
  2. Redundant data

How to organize it adequately?

Answer the question

In order to leave comments, you need to log in

2 answer(s)
S
Sergey c0re, 2019-12-18
@dblearn94

Same questions from different accounts??
I understand that this is the same or the essence is similar: Get the string with the maximum match? ??
instead of `movie_desc` - `setting_value` (see the query and examples below)
through window functions, you need to do it if on MySQL 8 (you did NOT specify a DBMS ...), the ranking function is row_number()

-- здесь я вынес параметры (домены, языки) в отдельное представление param,
-- которое определяется перед SELECT
-- это сделано, для того чтобы по всему запросу не искать и вписывать их
-- меняется все в одном месте:
WITH param AS (
  SELECT
      2 AS primary_domain_id,    -- id первичного домена
      1 AS secondary_domain_id,  -- id вторичного домена
      2 AS primary_language_id,  -- id первичного языка
      1 AS secondary_language_id -- id вторичного языка
    FROM dual
)
SELECT *
  FROM (
    SELECT m.*,
        row_number() over (
          partition by m.movie_id
          order by
          	case
          	  when m.domain_id = p.primary_domain_id then 100
          	  when m.domain_id = p.secondary_domain_id then 50
          	  else 1
            end DESC,
          	case
          	  when m.language_id = p.primary_language_id then 100
          	  when m.language_id = p.secondary_language_id then 50
          	  else 1
            end DESC
        ) rn
      FROM `movie_desc` m, param p
      WHERE (m.domain_id = p.primary_domain_id
          OR m.domain_id = p.secondary_domain_id
          OR m.domain_id IS NULL)
      AND (m.language_id = p.primary_language_id
          OR m.language_id = p.secondary_language_id
          OR m.language_id IS NULL)
  ) t
  WHERE t.rn = 1
;

Examples at:
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=f46bf1...
https://www.db-fiddle.com/f/8UigbxU6uNg6guU8ygKgrA/1
PS: if MySQL is older than 8th then try rewrite as described on the second page of the same article linked above.
www.sql-tutorial.ru/ru/book_row_number_function/pa...

L
Lazy @BojackHorseman, 2019-12-17
SQL

how very difficult

...
WHERE `domain_id` IS NULL OR `domain_id` = <value>
ORDER BY `domain_id` IS NOT NULL DESC
LIMIT 1

if there is a record with the required domain_id, then we will get it, otherwise the one for which domain_id is null.
well, by analogy, expand the logic for language_id

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question