Промежуточные таблицы базы данных «многие ко многим»: дополнительные поля - PullRequest
1 голос
/ 15 февраля 2011

Я создал таблицу «магазины» и «клиенты» и промежуточную таблицу Customers_shops. Каждый магазин имеет site_url веб-адрес, за исключением того, что некоторые клиенты используют альтернативный URL для доступа к сайту магазина (этот URL-адрес уникален для конкретного клиента).

В промежуточной таблице ниже я добавил дополнительное поле shop_site_url. Насколько я понимаю, это во 2-й нормализованной форме , поскольку поле the shop_site_url уникально для конкретного покупателя и магазина (поэтому не будет дублироваться для разных покупателей / магазинов). Кроме того, так как это зависит от клиента и магазина, я думаю, что это в третьей нормализованной форме. Я просто не привык использовать таблицу 'mapping' (customers_shops) для хранения дополнительных полей - имеет ли смысл приведенный ниже дизайн или мне следует зарезервировать промежуточные таблицы исключительно как a для преобразования многих во многие отношения с один к одному?

######
customers
######

id INT(11) NOT NULL PRIMARY KEY
name VARCHAR(80) NOT NULL

######
shops
######

id INT(11) NOT NULL PRIMARY KEY
site_url TEXT

######
customers_shops
######

id INT(11) NOT NULL PRIMARY KEY
customer_id INT(11) NOT NULL
shop_id INT(11) NOT NULL
shop_site_url TEXT //added for a specific url for customer

Спасибо

Ответы [ 5 ]

2 голосов
/ 15 февраля 2011

То, что вы называете «промежуточной» таблицей, не является специальным типом таблицы. Существует только один вид таблицы, и одинаковые принципы проектирования должны быть применимы ко всем.

1 голос
/ 15 февраля 2011

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

id cust_id  shop_id  shop_site_url
--
1  1000     2000     NULL
2  1000     2000     http://here-an-url.com
3  1000     2000     http://there-an-url.com
4  1000     2000     http://everywhere-an-url-url.com
5  1001     2000     NULL
6  1001     2000     http://here-an-url.com
7  1001     2000     http://there-an-url.com
8  1001     2000     http://everywhere-an-url-url.com

Хм. Это выглядит не очень хорошо. Давайте на минуту проигнорируем альтернативный URL. Чтобы создать таблицу, которая разрешает отношение m: n, вам нужно ограничение на столбцы, которые составляют отношение m: n.

create table customers_shops (
    customer_id integer not null references customers (customer_id),
    shop_id integer not null references shops (shop_id),
    primary key (customer_id, shop_id)
);

(я опустил столбец «id», потому что он имеет тенденцию затенять происходящее. Вы можете добавить его позже, если хотите.)

Вставьте пример данных. , , то

select customer_id as cust_id, shop_id
from customers_shops;

cust_id  shop_id
--
1000     2000
1001     2000
1000     2001
1001     2001

Это ближе. Вы должны иметь только одну строку для каждой комбинации клиента и магазина в этой таблице. (Это полезные данные даже без URL-адреса.) Что мы будем делать с альтернативными URL-адресами? Это зависит от нескольких вещей.

  • Имеют ли клиенты доступ к сайтам через только один URL, или они могут использовать больше чем один?

Если ответ «только один», то вы можете добавить в эту таблицу столбец для URL и сделать этот столбец уникальным. Это ключ-кандидат для этой таблицы.

Если ответ «больше, чем один - по крайней мере, URL сайта и альтернативный URL», то вам нужно принять больше решений об ограничениях, потому что изменение этой таблицы позволяет использовать несколько URL для каждой комбинации клиента и Магазин режет по этому требованию:

поле shop_site_url уникально для конкретный клиент и магазин (поэтому не будет дублироваться для разные клиенты / магазины)

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

  • клиент 'n' посетил веб-сайт для магазина "m", используя url 's'
  • клиенту 'n' разрешено посещать веб-сайт для магазина «м» с использованием альтернативных url 's'
1 голос
/ 15 февраля 2011

Ваша схема действительно имеет смысл, поскольку shop_site_url является атрибутом самих отношений. Возможно, вы захотите дать ему более осмысленное имя, чтобы отличить его от shops.site_url.

0 голосов
/ 15 февраля 2011

Отношения могут иметь атрибуты, так же как у сущностей могут быть атрибуты.

Атрибуты сущности входят в столбцы в таблицах сущностей. Атрибуты отношений, по крайней мере, для отношений «многие ко многим», входят в таблицы отношений.

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

0 голосов
/ 15 февраля 2011

Где бы вы разместили эту информацию?Это не атрибут магазина, и это не атрибут покупателя.Вы могли бы поместить это в отдельную таблицу, если вы хотите избежать столбца NULLable, но в итоге вам понадобится ссылка на промежуточную таблицу из этой новой таблицы, которая, вероятно, выглядела быстраннее для вас.

...