Решение SQL Design: я должен объединить эти таблицы? - PullRequest
2 голосов
/ 01 июня 2011

Я пытаюсь создать небольшую базу данных для клиента. У моего клиента есть организация, которая работает с государственными и частными школами; для каждой участвующей школы есть реализация (глава) в каждой школе.

Чтобы создать это, я собрал две таблицы; один для школ и один для глав. Однако я не уверен, что мне следует объединить их вместе. Таблицы следующие:

mysql> describe chapters;
+--------------------+------------------+------+-----+---------+----------------+
| Field              | Type             | Null | Key | Default | Extra          |
+--------------------+------------------+------+-----+---------+----------------+
| id                 | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| school_id          | int(10) unsigned | NO   | MUL |         |                |
| is_active          | tinyint(1)       | NO   |     | 1       |                |
| registration_date  | date             | YES  |     | NULL    |                |
| state_registration | varchar(10)      | YES  |     | NULL    |                |
| renewal_date       | date             | YES  |     | NULL    |                |
| population         | int(10) unsigned | YES  |     | NULL    |                |
+--------------------+------------------+------+-----+---------+----------------+
7 rows in set (0.01 sec)

mysql> describe schools;
+----------------------+------------------------------------+------+-----+---------+----------------+
| Field                | Type                               | Null | Key | Default | Extra          |
+----------------------+------------------------------------+------+-----+---------+----------------+
| id                   | int(10) unsigned                   | NO   | PRI | NULL    | auto_increment |
| full_name            | varchar(255)                       | NO   | MUL |         |                |
| classification       | enum('high','middle','elementary') | NO   |     |         |                |
| address              | varchar(255)                       | NO   |     |         |                |
| city                 | varchar(40)                        | NO   |     |         |                |
| state                | char(2)                            | NO   |     |         |                |
| zip                  | int(5) unsigned                    | NO   |     |         |                |
| principal_first_name | varchar(20)                        | YES  |     | NULL    |                |
| principal_last_name  | varchar(20)                        | YES  |     | NULL    |                |
| principal_email      | varchar(20)                        | YES  |     | NULL    |                |
| website              | varchar(20)                        | YES  |     | NULL    |                |
| population           | int(10) unsigned                   | YES  |     | NULL    |                |
+----------------------+------------------------------------+------+-----+---------+----------------+
12 rows in set (0.01 sec)

(Обратите внимание, что эти таблицы неполные - я еще не реализовал внешние ключи. Также, пожалуйста, игнорируйте размеры varchar для некоторых полей, они будут изменяться.)

До сих пор плюсы их разделения:

  1. Отдельные запросы школ и главы легче. Я не знаю, если это необходимо на данный момент, но это приятно делать.
  2. Я могу сделать главу неактивной без непосредственного влияния на информация о школе.
  3. Общее разделение данных - поля в «главы» имеют прямое отношение к сама глава, а не школа в котором оно существует. (Мне нравится организация - это имеет больше смысла мне. Также следует мантре «ничего, кроме ключа».)
  4. Если возможно, мы можем собрать школу данные без главы связано с этим, что может сделать смысл, если мы в конечном итоге хотим людей выбрать школу и заселить данные.

И минусы:

  1. Отдельные идентификаторы для школ и главы. Насколько я знаю, там будет когда-либо только один к одному отношения между двумя, так делать это может ввести больше сложность, которая может привести к ошибкам вниз по линии (например, импорт данных из таблицы, которая, к сожалению, что-то, что я буду делать много).
  2. Если соотношение один к одному, и идентификаторы - это поля auto_increment, Я предполагаю, что chapter_id и school_id в конечном итоге будет таким же - так почему бы просто не поместить их в одну таблицу?
  3. Из того, что я понимаю, главы на самом деле не опознаются на их собственные - они связаны со школой, и как таковой должен быть подмножество школа. Должны ли они действительно быть отдельные объекты в таблице?

Прямо сейчас я склоняюсь к тому, чтобы хранить их как два отдельных стола; кажется, что плюсы перевешивают минусы, но я хочу убедиться, что я не создаю ситуацию, которая может вызвать проблемы в будущем. Я связался со своим клиентом и пытаюсь получить более подробную информацию о данных, которые они хранят, и о том, что они хотят с ними делать, что, я думаю, действительно поможет. Тем не менее, я хотел бы получить мнение от хорошо информированных людей здесь; Есть ли что-нибудь, о чем я не думал? Суть в том, что я хочу все сделать правильно с первого раза.

Ответы [ 4 ]

3 голосов
/ 01 июня 2011

Я думаю, что они должны храниться отдельно.Но вы можете сделать главу подтипом школы (а школа - супертипом) и использовать один и тот же идентификатор.В другом месте базы данных, где вы используете SchoolID, вы имеете в виду школу, а где вы используете ChapterID, вы имеете в виду главу.

CREATE TABLE School (
   SchoolID int unsigned NOT NULL AUTO_INCREMENT,
   CONSTRAINT PK_School PRIMARY KEY (SchoolID)
)

CREATE TABLE Chapter (
   ChapterID int unsigned NOT NULL,
      CONSTRAINT PK_Chapter PRIMARY KEY (ChapterID)
      CONSTRAINT FK_Chapter_School FOREIGN KEY (ChapterID) REFERENCES School (SchoolID)
)

Теперь у вас не может быть главы, если сначала нет школы.Если бы произошло такое время, когда вам пришлось бы разрешить несколько глав в каждой школе, вы бы воссоздали таблицу глав с ChapterID в качестве идентификатора / автоинкремент, добавили столбец SchoolID, заполненный тем же значением, и поместили этот FK на этот элемент в School, ипродолжайте, как и раньше, только вставляя идентификатор в SchoolID вместо ChapterID.Если MySQL поддерживает вставку явных значений в столбец автоинкремента, то его автоматическое включение в SchoolID заблаговременно может избавить вас от проблем в будущем (если не поддерживается переключение обычного столбца на автоинкремент, и в этом случае проблем не возникает).

Дополнительные преимуществахранить их раздельно:

  • Вы можете установить связь с внешним ключом напрямую с SchoolID или ChapterID, чтобы данные, которые вы сохраняете, всегда были правильными (например, если глава еще не существует, вы не можете сохранитьсвязанные данные для такой вещи, пока она не будет создана).
  • Запрос каждой таблицы в отдельности будет работать лучше, поскольку строки не содержат посторонней информации.
  • Можно создать школу с определенными необходимыми столбцами, но глава оставлена ​​без создания (временно).Затем, когда он будет создан, в нем также могут быть столбцы NOT NULL.
1 голос
/ 01 июня 2011

держите их отдельно.

они могут быть 1-1 в настоящее время ... однако это явно отдельные понятия.

захотят ли они в конечном итоге ввести школы, в которых нет глав? возможно, как часть системы продаж?

может ли быть на самом деле только одна глава в школе или только одна активная глава? что насчет времени? возможно ли, что они будут запрашивать отчет со всеми главами за последние 10 лет в школе x?

0 голосов
/ 03 июня 2011

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

Кроме того, является ли требование фирмой 1-1 или у нее есть потенциал быть 1-многими?Если второе, сделайте это отдельной таблицей сейчас.Есть ли потенциал иметь школы без глав?Опять же, я бы держал их отдельно.

И как вы собираетесь запрашивать эти данные, будете ли вы обычно запрашивать данные о главе и школе в одних и тех же запросах, тогда вы можете поместить их в одну таблицу, еслиВы уверены, что нет возможности превратить это в отношения 1-многие.Однако правильное объединение с индексированными полями соединения должно быть быстрым в любом случае.

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

0 голосов
/ 01 июня 2011

Вы сказали, что ссылки всегда будут с 1 на 1, но всегда ли в школе есть глава, может ли она изменить главы? Если это так, то лучше хранить главы отдельно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...