Это хорошая нормализация базы данных? - PullRequest
1 голос
/ 26 июля 2011

Я новичок в использовании mysql, и я пытаюсь изучить лучшие практики. Я настроил похожую структуру, как показано ниже.

(основная таблица, содержащая все уникальные записи) TABLE = 'main_content'

+------------+---------------+------------------------------+-----------+
| content_id |  (deleted)    | title                        | member_id | 
+------------+---------------+------------------------------+-----------+
|          6 |               | This is a very spe?cal t|_st |      1    |
+------------+---------------+------------------------------+-----------+ 

(Предоставляет общее количество каждой сложности и объединяет идентификатор -> фактическое имя) TABLE = 'затруднение'

+---------------+-------------------+------------------+
| difficulty_id | difficulty_name   | difficulty_total |
+---------------+-------------------+------------------+
|             1 | Absolute Beginner |                1 |
|             2 | Beginner          |                1 | 
|             3 | Intermediate      |                0 |
|             4 | Advanced          |                0 |
|             5 | Expert            |                0 |
+---------------+-------------------+------------------+

(Эта таблица гарантирует, что для каждой записи можно вставить несколько значений. Например, эта конкретная запись указывает на то, что есть 2 трудности, связанные с представлением) TABLE = 'lookup_difficulty'

+------------+---------------+
| content_id | difficulty_id |
+------------+---------------+  
|          6 |             1 |
|          6 |             2 |
+------------+---------------+

Я объединяю все это в читаемый запрос:

SELECT group_concat(difficulty.difficulty_name) as difficulty, member.member_name
FROM main_content
INNER JOIN difficulty ON difficulty.difficulty_id 
IN (SELECT difficulty_id FROM main_content, lookup_difficulty WHERE lookup_difficulty.content_id = main_content.content_id )
INNER JOIN member ON member.member_id = main_content.member_id

Вышесказанное работает отлично, но мне интересно, если это хорошая практика. Я практически следовал за структурой, изложенной Пример нормализации базы данных Википедии .

Когда я запускаю вышеупомянутый запрос, используя EXPLAIN, он говорит: «Используя где; Использование буфера соединения », а также то, что я использую 2 ЗАВИСИМЫХ ПОСТАВКИ. Я не вижу способа НЕ использовать подзапросы для достижения того же эффекта, но опять же я новичок, так что, возможно, есть лучший способ ....

Ответы [ 2 ]

2 голосов
/ 26 июля 2011

Дизайн БД выглядит отлично - по вашему запросу вы можете переписать его исключительно с помощью таких объединений, как:

SELECT group_concat(difficulty.difficulty_name) as difficulty, member.member_name
      FROM main_content
        INNER JOIN lookup_difficulty ON main_content.id = lookup_difficulty.content_id
        INNER JOIN difficulty ON difficulty.id = lookup_difficulty.difficulty_id
        INNER JOIN member ON member.member_id = main_content.member_id
1 голос
/ 26 июля 2011

Если lookup_difficulty обеспечивает связь между content и difficulty, я бы посоветовал вам извлечь столбец difficulty_id из таблицы main_content.Поскольку вы можете иметь несколько поисков для каждого content_id, вам потребуется дополнительная бизнес-логика, чтобы определить, какой difficulty_id поместить в вашу таблицу main_content (или несколько записей в таблице main_content для каждого difficulty_id, ночто идет вразрез с практикой нормализации).Напримернаибольшее значение / наименьшее значение / случайное значение.В любом случае это не имеет особого смысла.

Кроме этого таблица выглядит хорошо.


Обновление

Увидел, что вы обновилитаблица:)

Просто как примечание.Использование IN может замедлить ваш запрос (IN может вызвать сканирование таблицы).В любом случае, так было раньше, но я уверен, что в наши дни компилятор SQL оптимизирует его довольно хорошо.

...