Первая база данных с ограничениями ссылочной целостности - предложения, отзывы, ошибки? - PullRequest
2 голосов
/ 03 декабря 2010

TARGET_RDBMS: MySQL-5.X-InnoDB («X» соответствует текущему стабильному выпуску)

ОБЩАЯ ИНФОРМАЦИЯ: Создание моей первой базы данных с истинными ограничениями ссылочной целостностиВ попытке получить обратную связь после создания «настоящего» DDL я сделал абстракцию, которая, как я считаю, охватывает «ощущение» базы данных;это только 3 таблицы из 20, все с ограничениями ссылочной целостности;Единственный шаблон, который, как я вижу, отсутствует, - это составная таблица ключей, в которой все равно нет данных, которые должны быть выгружены прямо сейчас, поэтому я просто сосредоточусь на первой итерации.

Образец данных / единица измеренияТест: Одна вещь, которую я не знаю, - это как создать пример набора данных, который обеспечит 100% -ное покрытие моделируемой ссылочной целостности - И построить «модульный тест» вокруг этих образцов данных и этого DDL:

Пример DLL:

(Примечание. Просто для ясности, стандарты LEGEND и именования являются ПРОСТО для этого примера, который я абстрагировал от «реальной» базы данных. Имена столбцов являются роботизированными по своей природеи предназначено для того, чтобы сделать смысл и взаимосвязь данного экземпляра как можно более понятными. Если у вас есть предложения по используемой системе обозначений, пожалуйста, не стесняйтесь комментировать. Я открыт для любых предложений. Спасибо!)

CREATE DATABASE sampleDB;

use sampleDB;

# ###############
# LEGEND
# - sID = surrogate key
# - nID = natural key
# - cID = common/shared across tables, but NOT unique/natural-key
# - PK = Primary Key
# - FK = Foreign Key
# - data01 = Sample data (non-key,not-shared-across-tables)
# - data02 = Sample data NOT NULL (non-key,not-shared-across-tables)
#
# - uID = user defined unique/natural key (NOTE: not used)

# ###############
# Behavior
# - create_timestamp (NOT NULL, updated on record creation, NOT update)
# - update_timestamp (NOT NULL, updated on record creation AND updates)

CREATE TABLE `TABLE_01` (
  `TABLE_01_sID_PK` MEDIUMINT NOT NULL AUTO_INCREMENT,
  `TABLE_01_cID` int(8) NOT NULL,
  `TABLE_01_data01` varchar(128) default NULL,
  `TABLE_01_data02`  varchar(128) default NULL,
  `create_timestamp` DATETIME DEFAULT NULL,
  `update_timestamp` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY  (`TABLE_01_sID_PK`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `TABLE_02` (
  `TABLE_02_sID_PK` MEDIUMINT NOT NULL AUTO_INCREMENT,
  `TABLE_02_nID_FK__TABLE_01_sID_PK` int(8) NOT NULL,
  `TABLE_02_cID` int(8) NOT NULL,
  `TABLE_02_data01` varchar(128) default NULL,
  `TABLE_02_data02` varchar(128) NOT NULL,
  `create_timestamp` DATETIME DEFAULT NULL,
  `update_timestamp` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`TABLE_02_sID_PK`),
  FOREIGN KEY (TABLE_02_nID_FK__TABLE_01_sID_PK) REFERENCES TABLE_01(TABLE_01_sID_PK),
  INDEX `TABLE_02_nID_FK__TABLE_01_sID_PK` (`TABLE_02_nID_FK__TABLE_01_sID_PK`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `TABLE_03` (
  `TABLE_03_sID_PK` MEDIUMINT NOT NULL AUTO_INCREMENT,
  `TABLE_03_nID_FK__TABLE_01_sID_PK` int(8) NOT NULL,
  `TABLE_03_nID_FK__TABLE_02_sID_PK` int(8) NOT NULL,
  `TABLE_03_cID` int(8) NOT NULL,
  `TABLE_03_data01` varchar(128) default NULL,
  `TABLE_03_data02` varchar(128) NOT NULL,
  `create_timestamp` DATETIME DEFAULT NULL,
  `update_timestamp` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`TABLE_03_sID_PK`),
  FOREIGN KEY (TABLE_03_nID_FK__TABLE_01_sID_PK) REFERENCES TABLE_01(TABLE_01_sID_PK),
  FOREIGN KEY (TABLE_03_nID_FK__TABLE_02_sID_PK) REFERENCES TABLE_02(TABLE_02_sID_PK),
  INDEX `TABLE_03_nID_FK__TABLE_01_sID_PK` (`TABLE_03_nID_FK__TABLE_01_sID_PK`),
  INDEX `TABLE_03_nID_FK__TABLE_02_sID_PK` (`TABLE_03_nID_FK__TABLE_02_sID_PK`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

SHOW TABLES;

# DROP DATABASE `sampleDB`;

# #######################
# View table definition
# DESC inserttablename;

# #######################
# View table create statement
# SHOW CREATE TABLE example;

Вопросы:

Любые отзывы о отсутствующих, неправильных или "лучших" способах построения этой базы данных приветствуются.Если у вас есть вопросы, просто прокомментируйте - и я отвечу как можно скорее.Еще раз, спасибо ~!

ОБНОВЛЕНИЕ (1):

Только что добавил "MEDIUMINT NOT NULL AUTO_INCREMENT" на ПК - не уверен, как я это отключил.

1 Ответ

3 голосов
/ 03 декабря 2010

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

Сказав это, пара очень субъективных мнений с моей стороны:

Я не люблю вставлятьвведите информацию в имена, такие как «TABLE_PERSON» или «PERSON_T», потому что это сбивает с толку, как только вы заменяете таблицу видом.В этот момент вы, конечно, могли бы искать и заменять «PERSON_T» на «PERSON_VW», но это как бы упускает из виду :) То же самое касается столбцов (хотя я не вижу этого в вашем примере).Подумайте о столбце "n_is_dead", который был изменен с числового на varchar.

Может ли строка существовать в таблице без создания (create_timestamp)?Объявите столбцы как NOT NULL, если они действительно не могут быть нулевыми.Фактически, я начинаю иметь NOT NULL в большинстве моих столбцов, потому что это заставляет меня задуматься о природе данных.

Я фанат именования столбца первичного ключа чем-то, кроме ID.Например,

company(company_id, etc)
person(person_id, company_id, firstname etc)

Я слышал, что у некоторых людей есть проблемы с O / R-преобразователями, которые хотят, чтобы у вас всегда был первичный ключ с именем "ID", но я не знаю, по-прежнему ли этоtrue, если это недавно изменилось.

Мне неясно, намеревались ли вы встраивать (s, n, c) в имена столбцов, чтобы указать, являются ли они суррогатным, естественным или общим ключом.Но я также не думаю, что это хорошая идея.Я чувствую, что это "раскроет" некоторые детали реализации, которые не вписываются в логическую модель естественным образом.

Похоже, вы выставляете / внедряете отношение внешнего ключа в имена столбцов.Я никогда не думал об этом, но я думаю, вы глубоко пожалеете об этом.Если не только потому, что это делает имена столбцов невыносимо уродливыми:)

При выборе имени для индекса.Единственный раз, когда я сожалею о присвоении имени индексу, это когда я смотрю на план выполнения и вижу, что «index_01» используется.Я всегда хотел бы, чтобы я поместил имя столбца в индекс, чтобы сделать его видимым в xplan.Я не знаю ограничения для имени индекса, но я всегда сталкиваюсь с ограничением в Oracle.Итак, попробуйте придумать какое-то правило, как сокращать имя таблицы.Здесь важно знать имя столбца.

Относительно смешанного регистра.Я всегда (без исключений) хожу с ALL_UPPER_CASE или all_lower_case.Причина в том, что в прошлом я был сожжен при переносе запросов между базами данных, когда они по-разному относятся к делу.В последнее время я использую all_lower_case, потому что типичный шрифт наших редакторов облегчает обнаружение орфографических ошибок в нижнем регистре, чем в верхнем.И когда я терплю неудачу, кажется, что редактор не кричит на меня;)

...