Идеальный способ представления вариантов с примечаниями в базе данных

#mysql #database #database-design #database-normalization

#mysql #База данных #database-design #база данных-нормализация

Вопрос:

У меня нет способа описать мою дилемму, но сказать, что я должен «оценить» тему с оценками A, B, C , и мне нужно предоставить замечания для каждого.

Каждая тема разделена на X категорий с Y тем, для которых требуется «оценка» и замечания.

 | Topic 1    | A | B | C | Remarks |
|------------|---|---|---|---------|
| Subtopic A |   |   |   |         |
| Subtopic B |   |   |   |         |
|------------|---|---|---|---------|
| Topic 2    | A | B | C | Remarks |
|------------|---|---|---|---------|
| Subtopic A |   |   |   |         |
| Subtopic B |   |   |   |         |
| Subtopic C |   |   |   |         |
| Subtopic D |   |   |   |         |
  

Область:

  • все подтемы являются необязательными
  • если дан ответ на оценку подтемы, то требуется замечание

Ограничения:

  • Я ограничен средой MySQL, отличной от Barracuda, и я планирую выделить 2048 байт для каждого замечания

(Только псевдокоды SQL, не возражайте, если они ошибочны)

Планируйте:

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

 TABLE topic_1 (
    id AUTO_INCREMENT UNIQUE PRIMARY KEY,
    subtopic_a ENUM('A', 'B', 'C') NULL,
    remarks_subtopic_a VARCHAR(2048) NULL,
    subtopic_b ENUM('A', 'B', 'C') NULL,
    remarks_subtopic_a VARCHAR(2048) NULL
) ENGINE=INNODB DEFAULT CHARSET=utf8;
  

но это ужасно, поскольку оценки не объявляются в одном месте.

План Б:

Создайте таблицу для всех подтем, их имена жестко закодированы, но ссылаются на оценки, объявленные в другой таблице. Все замечания распределяются по другим таблицам по темам и ограничениям ресурсов:

 INSERT INTO grades (grade)
VALUES ("A"), ("B"), ("C"); 

TABLE topics (
    id AUTO_INCREMENT UNIQUE PRIMARY KEY,
    topic_1_subtopic_a INT UNSIGNED NULL,
    FOREIGN KEY (topic_1_subtopic_a)
        REFERENCES grades(id)
        ON DELETE CASCADE
        ON UPDATE CASCADE,
    topic_1_subtopic_b INT UNSIGNED NULL,
    FOREIGN KEY (topic_1_subtopic_a)
        REFERENCES grades(id)
        ON DELETE CASCADE
        ON UPDATE CASCADE,
    topic_2_subtopic_a INT UNSIGNED NULL,
    FOREIGN KEY (topic_1_subtopic_a)
        REFERENCES grades(id)
        ON DELETE CASCADE
        ON UPDATE CASCADE,

    ...

) ENGINE=INNODB DEFAULT CHARSET=utf8;

TABLE remarks_topic_1 (
    id AUTO_INCREMENT UNIQUE PRIMARY KEY,
    subtopic_a VARCHAR(2048) NULL, 
    subtopic_b VARCHAR(2048) NULL
) ENGINE=INNODB DEFAULT CHARSET=utf8;

TABLE remarks_topic_2 (
    id AUTO_INCREMENT UNIQUE PRIMARY KEY,
    subtopic_a VARCHAR(2048) NULL, 
    subtopic_b VARCHAR(2048) NULL
    subtopic_c VARCHAR(2048) NULL, 
    subtopic_d VARCHAR(2048) NULL
) ENGINE=INNODB DEFAULT CHARSET=utf8;
  

План C:

Поскольку у нас есть шаблон подтемы, чтобы иметь следующие атрибуты:

  • супертопический
  • оценка
  • примечания

Создайте для этого таблицу, в которой контракт количества тем и их соответствующих подтем только «собран» и известен во внешнем интерфейсе; в фоновом режиме все они рассматриваются только как subtopic объекты базы данных:

 INSERT INTO grades (grade)
VALUES ("A"), ("B"), ("C"); 

TABLE subtopics (
    id AUTO_INCREMENT UNIQUE PRIMARY KEY,
    topic VARCHAR(100) NULL,
    subtopic INT UNSIGNED NULL,
    FOREIGN KEY (grades)
        REFERENCES grades(id)
        ON DELETE CASCADE
        ON UPDATE CASCADE,
    remarks VARCHAR(2048) NULL
) ENGINE=INNODB DEFAULT CHARSET=utf8;
  

Плюсы:

  • обобщенные шаблоны
  • grades определены в базе данных
  • не сложно сохранить один завершенный subtopic , учитывая remarks

Минусы:

  • интерфейс знает только контракт / бизнес-логику
  • темы и подтемы не являются жестко запрограммированными

Является ли план C хорошим способом для начала? Или есть лучший способ справиться с этим?

Комментарии:

1. Не могли бы вы немного пояснить с помощью нескольких примеров. Вы заявляете, что «Каждая тема разделена на X категорий с Y тем ..» , Но слово категория отсутствует в схеме? Может ли подтема быть самой темой? Является Subtopic A ли та же подтема для Topic 1 и Topic 2 ? Нужно понять, являются ли темы частью иерархии? Кто оценивает темы и сколько раз?

Ответ №1:

Да, план C — лучший дизайн, потому что он более нормализован и масштабируем. Это предлагаемый способ моделирования СУБД. Вы также можете перенести столбец «Тема» в отдельную таблицу или иметь отношения «родитель-потомок» в той же таблице, чтобы вам было проще управлять темами. В противном случае тема будет дублироваться среди всех подтем, и вам, возможно, придется обновлять все строки, если в будущем произойдут какие-либо изменения.

Все другие упомянутые подходы имеют некоторые проблемы с масштабируемостью и ремонтопригодностью.

Комментарии:

1. Спасибо, я думаю Topic , будет еще один FK.