buys
называется таблицей ассоциации или таблицей соединений, таблицей отношений или любым другим числом имен. Я бы не назвал его «сущностью», если он действительно не является сущностью в вашей системе (представляет человека, место, понятие вещи или событие, которое может быть однозначно идентифицировано, представляет интерес для бизнеса, и мы можем хранить информация о.)
Определение таблицы для таблицы ассоциации может выглядеть примерно так:
CREATE TABLE buys
( prod_id NUMBER(5,0) NOT NULL COMMENT 'composite PK, FK ref products.prod_id'
, cus_id NUMBER(5,0) NOT NULL COMMENT 'composite PK, FK ref customers.cus_id'
, PRIMARY KEY (prod_id, cus_id)
, UNIQUE KEY buys_UX1 (cus_id, prod_id)
, CONSTRAINT FK_buys_products FOREIGN KEY (prod_id) REFERENCES products (prod_id)
ON DELETE CASCADE ON UPDATE CASCADE
, CONSTRAINT FK_buys_customers FOREIGN KEY (cus_id) REFERENCES customers (cus_id)
ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB
;
Примечание. Я не верю, что NUMBER(5,0)
является допустимым типом данных MySQL. Для столбцов первичного ключа я обычно использую целочисленный тип данных INT
или BIGINT
. Но столбцы внешнего ключа должны точно соответствовать типу данных указанных основных столбцов, поэтому я использовал NUMBER(5,0)
в качестве копии типа данных столбцов, на которые имеются ссылки.
Многозначный атрибут может быть реализован как дочерняя таблица, отношение один ко многим. Но я не вижу никаких признаков многозначного атрибута в модели.
Составной атрибут может быть реализован в виде отдельной таблицы. Но я бы не пошел туда, если бы не было варианта использования, который сделал бы это выгодным.
Моим личным предпочтением для обработки составных атрибутов будет простой префикс имен столбцов. Например, в качестве указания на то, что эти столбцы являются компонентами атрибута «имя» ...
cus_name_title
cus_name_last
cus_name_first
cus_name_suffix
Аналогично, для атрибута «почтовый адрес»
cus_addr_street
cus_addr_line2
cus_addr_city
cus_addr_state
cus_addr_postal_code
(Некоторые другие реляционные базы данных поддерживают объявление составных «типов»; я не верю, что эта функция доступна в MySQL. (И я бы не стал представлять составной атрибут в виде объекта JSON.)
Ограничение PRIMARY KEY
уже применяет NOT NULL для всех столбцов в первичном ключе. Но не мешает также явно включить ограничение NOT NULL
. Я предпочитаю добавить ограничение NOT NULL
для любого столбца, в который мы не хотим принимать значения NULL.
Followup
Для многозначных атрибутов объекта (атрибут, который может иметь ноль, одно или несколько значений для одного экземпляра), общий шаблон представляет собой дочернюю таблицу.
Возьмите в качестве примера номер телефона клиента.
Мы можем создать таблицу с внешним ключом, ссылаясь на cus_id у клиентов.
CREATE TABLE cus_phone_numbers
( id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT 'PK'
, cus_id NUMBER(5,0) NOT NULL COMMENT 'FK ref customers.cus_id'
, phone_type VARCHAR(80) COMMENT 'e.g. main, mobile, office, fax'
, phone_number VARCHAR(80)
, CONSTRAINT FK_cus_phone_numbers_customers
FOREIGN KEY (cus_id) REFERENCES customers (cus_id)
ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB
;
Например, клиент с тремя телефонными номерами будет иметь три строки в таблице телефонных номеров. Клиент без номера телефона будет иметь нулевые строки в таблице.
cus_id phone_type phone_number
------ ---------- ---------------
42 main 1 xxx-xxx-1111
42 office xxx-xxx-1212
42 fax xxx-xxx-3333
112 service xxx-xxx-7701
112 delivery xxx-xxx-7702
То есть многозначные атрибуты ... и атрибут объекта, который может иметь ноль, одно или несколько значений.
Атрибут составной состоит из нескольких атрибутов компонента. Например, атрибут имени клиента может быть комбинацией нескольких простых атрибутов:
title/salutation 'Major'
first name 'Charles'
middle name 'Emerson'
last name 'Winchester'
suffix 'III'
nickname ''
Всегда можно разделить некоторые атрибуты объекта на отдельные таблицы, будь то простые или составные атрибуты. Одна из наиболее распространенных причин, по которой мы это делаем, - поддержка нескольких значений. Но мы можем сделать это и для атрибутов с одним значением.
Рассмотрим атрибут «номер телефона». Это может быть смоделировано как составной атрибут:
country code +1
area code 888
exchange number 467
line number 4355