Как правильно реализовать связь "многие-ко-многим"
От: ViktorZ  
Дата: 24.02.08 14:15
Оценка:
Возникла у меня с коллегами дискурсия на тему, как правильно реализовать связь «многие-ко-многим» в базе данных. Для меня, сомнений нет, но вот коллега настаивает на своём варианте.
Условия задачи:
Есть две таблицы:
CREATE TABLE [dbo].[users](
[userid] [int] IDENTITY(1,1) NOT NULL,
[username] [varchar](50) NOT NULL,
CONSTRAINT [PK_users] PRIMARY KEY CLUSTERED
(
[userid] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

И
CREATE TABLE [dbo].[roles](
[roleid] [int] IDENTITY(1,1) NOT NULL,
[rolename] [varchar](50) NOT NULL,
CONSTRAINT [PK_roles] PRIMARY KEY CLUSTERED
(
[roleid] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

Необходимо реализовать связь «многие-ко-многим» между этими таблицами.

Возможные варианты решения:
1) Стандартный вариант, везде описанный :
CREATE TABLE [dbo].[user_roles](
[userid] [int] NOT NULL,
[roleid] [int] NOT NULL,
CONSTRAINT [PK_user_roles] PRIMARY KEY NONCLUSTERED
(
[userid] ASC,
[roleid] ASC
))

GO
ALTER TABLE [dbo].[user_roles] WITH CHECK ADD CONSTRAINT [FK_role] FOREIGN KEY([roleid])
REFERENCES [dbo].[roles] ([roleid])
GO
ALTER TABLE [dbo].[user_roles] CHECK CONSTRAINT [FK_role]
GO
ALTER TABLE [dbo].[user_roles] WITH CHECK ADD CONSTRAINT [FK_user] FOREIGN KEY([userid])
REFERENCES [dbo].[users] ([userid])
GO
ALTER TABLE [dbo].[user_roles] CHECK CONSTRAINT [FK_user]
GO

2) Вариант предложенный коллегой:
CREATE TABLE [dbo].[user_roles2](
[user_roles_id] [int] IDENTITY(1,1) NOT NULL,
[userid] [int] NOT NULL,
[roleid] [int] NOT NULL,
CONSTRAINT [PK_user_roles2] PRIMARY KEY CLUSTERED
(
[user_roles_id] ASC
))
GO

CREATE UNIQUE NONCLUSTERED INDEX [IX_unique_user_roles] ON [dbo].[user_roles2]
(
[userid] ASC,
[roleid] ASC
)
GO

ALTER TABLE [dbo].[user_roles2] WITH CHECK ADD CONSTRAINT [FK_user_roles2_roles] FOREIGN KEY([roleid])
REFERENCES [dbo].[roles] ([roleid])
GO
ALTER TABLE [dbo].[user_roles2] CHECK CONSTRAINT [FK_user_roles2_roles]
GO
ALTER TABLE [dbo].[user_roles2] WITH CHECK ADD CONSTRAINT [FK_user_roles2_user] FOREIGN KEY([userid])
REFERENCES [dbo].[users] ([userid])
GO
ALTER TABLE [dbo].[user_roles2] CHECK CONSTRAINT [FK_user_roles2_user]
GO

Аргумент против второго варианта – дополнительный индекс увеличивает время вставки записей.
Аргументы коллеги за второй вариант:
— я традиционно так делал, и ничего
— при редактировании записей в таблице user_roles2 поле user_roles_id можно использовать в разделе where оператора update .
Уважаемое сообщество, посоветуйте, как лучше убедить коллегу правильно реализовать связь «многие-ко-многим».
Re: Как правильно реализовать связь "многие-ко-многим"
От: Дм.Григорьев  
Дата: 24.02.08 15:09
Оценка:
Здравствуйте, ViktorZ, Вы писали:

VZ>- я традиционно так делал, и ничего


Сильный аргумент!

VZ>- при редактировании записей в таблице user_roles2 поле user_roles_id можно использовать в разделе where оператора update.


Ну дык в твоём варианте тоже есть составной primary key.

VZ>как лучше убедить коллегу правильно реализовать связь «многие-ко-многим».


А зачем?

- Глянь-ка! — столпился народ у ворот,
— Старый-то едет, а малый идёт!

... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
http://dimgel.ru/lib.web — thin, stateless, strictly typed Scala web framework.
Re: Как правильно реализовать связь "многие-ко-многим"
От: Formidable  
Дата: 24.02.08 16:49
Оценка: +1
Здравствуйте, ViktorZ, Вы писали:
Самое смешное, что оба варианта правильные, тут нужно выбирать именно исходя из логики задачи, первый вариант:
1. Занимает на 50% меньше места
2. Более эффективен для вставки
3. Не предполагает update элементов отношений, т.к. отношение ОПРЕДЕЛЯЕТСЯ этими элементами.
Второй вариант.
1. ОПРЕДЕЛЯЕТСЯ своим ключем и предполагает UPDATE элементов отношений.
2. Более гибкий для последующих изменений, так как отношение фактически выделяется в отдельную самостоятельную сущность. В последствии его можно будет без особых проблем преобразовать в отношения с какими-то другими свойствами (например, роль действительна для пользователя только в рабочее время).
Re[2]: Как правильно реализовать связь "многие-ко-многим"
От: 1kulibin Украина http://ua.linkedin.com/pub/oleg-anedchenko/25/111/83b
Дата: 24.02.08 18:27
Оценка:
Здравствуйте, Formidable, Вы писали:

F>Здравствуйте, ViktorZ, Вы писали:

F>Самое смешное, что оба варианта правильные, тут нужно выбирать именно исходя из логики задачи, первый вариант:
F>1. Занимает на 50% меньше места
F>2. Более эффективен для вставки
F>3. Не предполагает update элементов отношений, т.к. отношение ОПРЕДЕЛЯЕТСЯ этими элементами.
F>Второй вариант.
F>1. ОПРЕДЕЛЯЕТСЯ своим ключем и предполагает UPDATE элементов отношений.
F>2. Более гибкий для последующих изменений, так как отношение фактически выделяется в отдельную самостоятельную сущность. В последствии его можно будет без особых проблем преобразовать в отношения с какими-то другими свойствами (например, роль действительна для пользователя только в рабочее время).

поддерживаю. правда могу так же сказать "я тоже всегда так делал" — про второй вариант — и вообще всегда создаю таблицы с id — так с ними удобнее работать.
Re: Как правильно реализовать связь "многие-ко-многим"
От: Flying Dutchman Украина  
Дата: 24.02.08 21:20
Оценка: 1 (1) +1
Здравствуйте, ViktorZ, Вы писали:


VZ>Аргумент против второго варианта – дополнительный индекс увеличивает время вставки записей.

VZ>Аргументы коллеги за второй вариант:
VZ>- я традиционно так делал, и ничего
VZ>- при редактировании записей в таблице user_roles2 поле user_roles_id можно использовать в разделе where оператора update .

С таким же успехом можно использовать в разделе where поля userid и roleid.

Главный аргумент против второго варианта — он сложнее. Для реализации той же самой
функциональности добавлена одна колонка и один Unique Constraint. Поэтому следует выбрать первый вариант,
так как он проще.

VZ>Уважаемое сообщество, посоветуйте, как лучше убедить коллегу правильно реализовать связь «многие-ко-многим».


Скажи коллеге, что в философии существует принцип, называемый "Бритва Оккама". Он гласит: "не
умножай сущностей без необходимости". Применительно к программированию это значит,
что не стоит решать задачу сложным путем, если можно это сделать более простым путем.
Также можно сослаться на KISS-принцип.
Re[2]: Как правильно реализовать связь "многие-ко-многим"
От: Flying Dutchman Украина  
Дата: 24.02.08 21:32
Оценка: 3 (1) +1
Здравствуйте, Formidable, Вы писали:

F>Здравствуйте, ViktorZ, Вы писали:

F>Самое смешное, что оба варианта правильные, тут нужно выбирать именно исходя из логики задачи, первый вариант:

Первый вариант проще

F>1. Занимает на 50% меньше места

F>2. Более эффективен для вставки
F>3. Не предполагает update элементов отношений, т.к. отношение ОПРЕДЕЛЯЕТСЯ этими элементами.

Почему же не предполагает ? Что, нельзя сделать update для этой таблицы ???

F>Второй вариант.

F>1. ОПРЕДЕЛЯЕТСЯ своим ключем и предполагает UPDATE элементов отношений.

Никакой разница с точки зрения Update между обоими вариантами нет.

F>2. Более гибкий для последующих изменений, так как отношение фактически выделяется в отдельную самостоятельную сущность. В последствии его можно будет без особых проблем преобразовать в отношения с какими-то другими свойствами (например, роль действительна для пользователя только в рабочее время).


Если столбец понадобится в будущем, то и добавить его надо в будущем, чтобы не засорять
структуру базы данных сейчас.
Re[3]: Как правильно реализовать связь "многие-ко-многим"
От: Flying Dutchman Украина  
Дата: 24.02.08 21:34
Оценка:
Здравствуйте, 1kulibin, Вы писали:

1>Здравствуйте, Formidable, Вы писали:


F>>Здравствуйте, ViktorZ, Вы писали:

F>>Самое смешное, что оба варианта правильные, тут нужно выбирать именно исходя из логики задачи, первый вариант:
F>>1. Занимает на 50% меньше места
F>>2. Более эффективен для вставки
F>>3. Не предполагает update элементов отношений, т.к. отношение ОПРЕДЕЛЯЕТСЯ этими элементами.
F>>Второй вариант.
F>>1. ОПРЕДЕЛЯЕТСЯ своим ключем и предполагает UPDATE элементов отношений.
F>>2. Более гибкий для последующих изменений, так как отношение фактически выделяется в отдельную самостоятельную сущность. В последствии его можно будет без особых проблем преобразовать в отношения с какими-то другими свойствами (например, роль действительна для пользователя только в рабочее время).

1>поддерживаю. правда могу так же сказать "я тоже всегда так делал" — про второй вариант — и вообще всегда создаю таблицы с id — так с ними удобнее работать.


Так удобнее работать с таблицами-сущностями. Добавление же такого id в таблицу-отношение удобств не добавляет,
а схему базы данных усложняет.
Re: Как правильно реализовать связь "многие-ко-многим"
От: Аноним  
Дата: 24.02.08 21:47
Оценка: +1
Уже правильно заметили, что второй вариант имеет смысл, когда элемент такого отношения — как бы, отдельная сущность, и её часто надо отдельно показывать, обновлять (строить URL-ы, запоминать ссылки где-то вне базы)...
На практике, у меня была куча таких отношений, но отдельные строки в них никогда не обновлялись (и вообще, непонятно, когда можно обновлять такие строки, ведь id постоянен или обновляется по foreign key), только удалялись, и не отображались отдельно, а только в связанном виде.
Тем более, в первом случае, для поиска в таком отношении достаточно PRIMARY KEY с выбранным порядком столбцов и, возможно, индекс на втором столбце, а во втором случае индексов будет больше.
Re[3]: Как правильно реализовать связь "многие-ко-многим"
От: Formidable  
Дата: 24.02.08 23:12
Оценка:
Здравствуйте, Flying Dutchman, Вы писали:

FD>Здравствуйте, Formidable, Вы писали:



FD>Первый вариант проще

Совершенно верно, выбор и есть "проще и быстрее" VS гибче. И то и другое правильное, выбор за проектировщиком.

F>>1. Занимает на 50% меньше места

F>>2. Более эффективен для вставки
F>>3. Не предполагает update элементов отношений, т.к. отношение ОПРЕДЕЛЯЕТСЯ этими элементами.

FD>Почему же не предполагает ? Что, нельзя сделать update для этой таблицы ???

Можно, и налететь на все прелести UPDATE PRIMARY KEY.

F>>Второй вариант.

F>>1. ОПРЕДЕЛЯЕТСЯ своим ключем и предполагает UPDATE элементов отношений.

FD>Никакой разница с точки зрения Update между обоими вариантами нет.

Тут фактически идет вопрос о натуральном (1 вариант) и суррогатном ключе, со всеми последствиями. Тонкость в том что сущность тоже суррогатная, поэтому и требования к ней другие. Но опять таки если появляются физические атрибуты для этой связи...

FD>Если столбец понадобится в будущем, то и добавить его надо в будущем, чтобы не засорять

FD>структуру базы данных сейчас.
Тут не о столбце будет идти речь, а о структуре таблицы, опять таки все проблемы, которые возникают с натуральными ключами тут и вылезут. Просто дороже будет стоить такое изменения. Другое дело что тут думать нужно о вероятностях таких изменений и об рисках.
Re: Как правильно реализовать связь "многие-ко-многим"
От: Centaur Россия  
Дата: 25.02.08 03:05
Оценка: +2
Здравствуйте, ViktorZ, Вы писали:

VZ>Возникла у меня с коллегами дискурсия на тему, как правильно реализовать связь «многие-ко-многим» в базе данных. Для меня, сомнений нет, но вот коллега настаивает на своём варианте.


VZ>2) Вариант предложенный коллегой:

VZ>[user_roles_id] [int] IDENTITY(1,1) NOT NULL,
VZ>[userid] [int] NOT NULL,
VZ>[roleid] [int] NOT NULL,

VZ>Аргументы коллеги за второй вариант:

VZ>- при редактировании записей в таблице user_roles2 поле user_roles_id можно использовать в разделе where оператора update .

Контраргумент: записи в таблице user_roles2 никогда не редактируются. Они только удаляются и добавляются, и в исключительно редких случаях (изменение первичного ключа user или role) обновляются все скопом, да и то через каскадный foreign key.
Re: Как правильно реализовать связь "многие-ко-многим"
От: Аноним  
Дата: 25.02.08 08:00
Оценка:
Огромное спасибо всем, кто ответил на вопрос.

Сначала хочу покаяться, аргумент о том, что связь "многие-ко-многим" в будущем может стать отдельной сущностью и тогда отдельное поле для первичного ключа понадобится также приводился моим коллегой в поддержку второго варианта. Когда писал пост, я об этом аргументе забыл. Кроме того, в нашем проекте необходимо реализовать несколько связей "многие-ко-многим" и одна из них является самостоятельной сущностью. В случае реализации именно такой одной связи, отдельное поле для первичного ключа действительно необходимо.

Хочу резюмировать результат дискурсии в форуме:

Разумным аргументом за дополнительное поле для первичного ключа является замечание по поводу того, что в будущем возможно появиться дополнительная сущность и тогда будет удобней расширять структуру БД.
Разумным контр-аргументом для этого аргумента есть замечание о том, что когда понадобиться добавлять новую сущность тогда и поле для первичного индекса добавить можно. Ведь никаких проблем, с переходом с первого варианта на второй не предвидится.

Разумным, и как мне кажется очень весомым, аргументом за первый вариант есть то, что во втором варианте уменьшается производительность вставки и обновления записей, так как требуется перестраивать не один а два индекса.
В подтверждение этого аргумента хочу процитировать, как мне кажется, хорошую книгу издательства Wrox, автора Роберта Виейра "Программирование баз данных Microsoft SQL Server 2005 Базовый Курс". Цитата — один из пунктов резюме главы 9 "Структуры памяти и индексные структуры SQL Server": "Применение индексов может повлеч за собой не только повышение, но и снижение производительности, поэтому необходимо тщательно обосновывать создание каждого индекса и не формировать индексы, которые в действительности не требуются."
Re[2]: Как правильно реализовать связь "многие-ко-многим"
От: MasterZiv СССР  
Дата: 25.02.08 17:26
Оценка: 3 (1) +1
Аноним 570 пишет:

> Сначала хочу покаяться, аргумент о том, что связь "многие-ко-многим" в

> будущем может стать отдельной сущностью и тогда отдельное поле для
> первичного ключа понадобится также приводился моим коллегой в поддержку
> второго варианта.

Ну так ничего страшного не будет и в первом случае. Будет просто
таблица (сущность), PK которой состоит из 2-х полей.

Знаешь еще какой довод бывает за 2-ой способ ?
Некоторые люди просто не умеют работать (писать запросы)
с таблицами с составными ключами, и, по низкой своей квалификации,
лепят везде поле ID с IDENTITY без разбору, надо это или нет.

> случае реализации именно такой одной связи, отдельное поле для

> первичного ключа действительно необходимо.

Неправда, оно НЕ НЕОБХОДИМО. Можно делать и самостоятельную
сущность с PK из нескольких полей. В чем проблема-то ?

> Разумным аргументом за дополнительное поле для первичного ключа является

> замечание по поводу того, что в будущем возможно появиться
> дополнительная сущность и тогда будет удобней расширять структуру БД.

Нет, это НЕ разумный аргумент. А вообще фигня. Это вообще не аргумент,
потому что использует предположение. А БД надо проектировать исходя из
каких-то реалий. И плюс — не аргумент, потому что базируется на ложном
предположении, что любая сущность должна идентифицироваться PK с одним полем.

> Разумным, и как мне кажется очень весомым, аргументом за первый вариант

> есть то, что во втором варианте уменьшается производительность вставки и
> обновления записей, так как требуется перестраивать не один а два индекса.

Не, не два, а три. Ты еще один индекс там не нарисовал, а он по-любому
понадобится.
Posted via RSDN NNTP Server 2.1 beta
Re[3]: Как правильно реализовать связь "многие-ко-многим"
От: 1kulibin Украина http://ua.linkedin.com/pub/oleg-anedchenko/25/111/83b
Дата: 25.02.08 21:25
Оценка:
Здравствуйте, MasterZiv, Вы писали:

MZ>Аноним 570 пишет:


>> Сначала хочу покаяться, аргумент о том, что связь "многие-ко-многим" в

>> будущем может стать отдельной сущностью и тогда отдельное поле для
>> первичного ключа понадобится также приводился моим коллегой в поддержку
>> второго варианта.

MZ>Ну так ничего страшного не будет и в первом случае. Будет просто

MZ>таблица (сущность), PK которой состоит из 2-х полей.
согласен — логично
MZ>Знаешь еще какой довод бывает за 2-ой способ ?
MZ>Некоторые люди просто не умеют работать (писать запросы)
MZ>с таблицами с составными ключами, и, по низкой своей квалификации,
MZ>лепят везде поле ID с IDENTITY без разбору, надо это или нет.
не согласен. думаю скорее наоборот — дальше обосную. дело то не в запросах — на самом деле.
>> случае реализации именно такой одной связи, отдельное поле для
>> первичного ключа действительно необходимо.

MZ>Неправда, оно НЕ НЕОБХОДИМО. Можно делать и самостоятельную

MZ>сущность с PK из нескольких полей. В чем проблема-то ?

>> Разумным аргументом за дополнительное поле для первичного ключа является

>> замечание по поводу того, что в будущем возможно появиться
>> дополнительная сущность и тогда будет удобней расширять структуру БД.

MZ>Нет, это НЕ разумный аргумент. А вообще фигня. Это вообще не аргумент,

MZ>потому что использует предположение. А БД надо проектировать исходя из
MZ>каких-то реалий. И плюс — не аргумент, потому что базируется на ложном
MZ>предположении, что любая сущность должна идентифицироваться PK с одним полем.

>> Разумным, и как мне кажется очень весомым, аргументом за первый вариант

>> есть то, что во втором варианте уменьшается производительность вставки и
>> обновления записей, так как требуется перестраивать не один а два индекса.

MZ>Не, не два, а три. Ты еще один индекс там не нарисовал, а он по-любому

MZ>понадобится.
вобщем я всегда id автоинкрементный везде тыкаю — и уже и подзабыл честно говоря зачем .
сейчас вот вспомнил — это однако для упрощения работы с таблицей на клиентском приложении — при конкурентном доступе. Т.е. такая ситуация: один чел на клиенте получил запись с двойным вашим примари кеем (1,1) допустим. пока он тупил другой чел отредактировал его на (2,2). потом первый чел говорит серверу, мол update some_table set f1=3, f2=3 where f1=1 and f2=1. а потом получается что? получается что клиентское приложения должно сказать первому челу — изините мол, ошибка конкурентного доступа, вините в этом чела2 — или кого винить?! а винить надо MasterZiv — за то, что он такой умный и умеет обращаться с запросами с составным примари кей . а вот если у нас будет в таблице этой id — НИКОГДА не редактируемый пользователем — тогда у нас всё будет просто и ясно — хотя и согласен про три индекса — однако думаю оно того стоит. ну или по крайней мере надо уже выбирать что когда нужнее.
можно конечно блокировки использовать — но это сейчас не модно . да — и ещё вспомнил — вроде как для такого пихаемого везде id и ещё там подобных вещей есть и термин специальный — конкуренси колумн. как-то так — поправьте если дето заврался .
Re[4]: Как правильно реализовать связь "многие-ко-многим"
От: _d_m_  
Дата: 25.02.08 21:50
Оценка: 3 (1) +1
Здравствуйте, 1kulibin, Вы писали:

1>вобщем я всегда id автоинкрементный везде тыкаю — и уже и подзабыл честно говоря зачем .


Судя по всему — никогда не писал распределенных систем.

1> сейчас вот вспомнил — это однако для упрощения работы с таблицей на клиентском приложении — при конкурентном доступе. Т.е. такая ситуация: один чел на клиенте получил запись с двойным вашим примари кеем (1,1) допустим. пока он тупил другой чел отредактировал его на (2,2). потом первый чел говорит серверу, мол update some_table set f1=3, f2=3 where f1=1 and f2=1. а потом получается что? получается что клиентское приложения должно сказать первому челу — изините мол, ошибка конкурентного доступа, вините в этом чела2 — или кого винить?! а винить надо MasterZiv — за то, что он такой умный и умеет обращаться с запросами с составным примари кей . а вот если у нас будет в таблице этой id — НИКОГДА не редактируемый пользователем — тогда у нас всё будет просто и ясно — хотя и согласен про три индекса — однако думаю оно того стоит. ну или по крайней мере надо уже выбирать что когда нужнее.


В смысле, просто и ясно? Проблема потерянного обновления никуда не денется: в случае составного ключа — обновление потеряет первый "чел"; в случае дополнительного суррогатного ключа — второй "чел". Те же яйца — вид в профиль. Так что же здесь "просто и ясно"?

1>можно конечно блокировки использовать — но это сейчас не модно . да — и ещё вспомнил — вроде как для такого пихаемого везде id и ещё там подобных вещей есть и термин специальный — конкуренси колумн. как-то так — поправьте если дето заврался .


Ф топку! Тебе еще много знаний надо получить по базам данных.
Re[4]: Как правильно реализовать связь "многие-ко-многим"
От: ViktorZ  
Дата: 26.02.08 06:57
Оценка:
Здравствуйте, 1kulibin, Вы писали:

1>вобщем я всегда id автоинкрементный везде тыкаю — и уже и подзабыл честно говоря зачем .

1> сейчас вот вспомнил — это однако для упрощения работы с таблицей на клиентском приложении — при конкурентном доступе. Т.е. такая ситуация: один чел на клиенте получил запись с двойным вашим примари кеем (1,1) допустим. пока он тупил другой чел отредактировал его на (2,2). потом первый чел говорит серверу, мол update some_table set f1=3, f2=3 where f1=1 and f2=1. а потом получается что? получается что клиентское приложения должно сказать первому челу — изините мол, ошибка конкурентного доступа, вините в этом чела2 — или кого винить?! а винить надо MasterZiv — за то, что он такой умный и умеет обращаться с запросами с составным примари кей . а вот если у нас будет в таблице этой id — НИКОГДА не редактируемый пользователем — тогда у нас всё будет просто и ясно — хотя и согласен про три индекса — однако думаю оно того стоит. ну или по крайней мере надо уже выбирать что когда нужнее.
1>можно конечно блокировки использовать — но это сейчас не модно . да — и ещё вспомнил — вроде как для такого пихаемого везде id и ещё там подобных вещей есть и термин специальный — конкуренси колумн. как-то так — поправьте если дето заврался .

В данном случае, при реализации связи "многие-ко-многим", програмируя клиентскую часть Вы не будете вызывать update. Будете вызывать insert или delete.

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

Да, действительно можно реализовать оповещение пользователя об уже внесённых изменениях перед апдейтом при любой структуре таблицы с помощью столбца, где хранится версия строки в виде временной метки или гуида.
Re[3]: Как правильно реализовать связь "многие-ко-многим"
От: ViktorZ  
Дата: 26.02.08 07:00
Оценка:
Здравствуйте, MasterZiv, Вы писали:

MZ>Аноним 570 пишет:


>> Сначала хочу покаяться, аргумент о том, что связь "многие-ко-многим" в

>> будущем может стать отдельной сущностью и тогда отдельное поле для
>> первичного ключа понадобится также приводился моим коллегой в поддержку
>> второго варианта.

MZ>Ну так ничего страшного не будет и в первом случае. Будет просто

MZ>таблица (сущность), PK которой состоит из 2-х полей.

MZ>Знаешь еще какой довод бывает за 2-ой способ ?

MZ>Некоторые люди просто не умеют работать (писать запросы)
MZ>с таблицами с составными ключами, и, по низкой своей квалификации,
MZ>лепят везде поле ID с IDENTITY без разбору, надо это или нет.

>> случае реализации именно такой одной связи, отдельное поле для

>> первичного ключа действительно необходимо.

MZ>Неправда, оно НЕ НЕОБХОДИМО. Можно делать и самостоятельную

MZ>сущность с PK из нескольких полей. В чем проблема-то ?

>> Разумным аргументом за дополнительное поле для первичного ключа является

>> замечание по поводу того, что в будущем возможно появиться
>> дополнительная сущность и тогда будет удобней расширять структуру БД.

MZ>Нет, это НЕ разумный аргумент. А вообще фигня. Это вообще не аргумент,

MZ>потому что использует предположение. А БД надо проектировать исходя из
MZ>каких-то реалий. И плюс — не аргумент, потому что базируется на ложном
MZ>предположении, что любая сущность должна идентифицироваться PK с одним полем.

>> Разумным, и как мне кажется очень весомым, аргументом за первый вариант

>> есть то, что во втором варианте уменьшается производительность вставки и
>> обновления записей, так как требуется перестраивать не один а два индекса.

MZ>Не, не два, а три. Ты еще один индекс там не нарисовал, а он по-любому

MZ>понадобится.

Спасибо за хороший ответ.

А какой индекс ещё понадобится?
Re: Как правильно реализовать связь "многие-ко-многим"
От: ViktorZ  
Дата: 26.02.08 07:20
Оценка:
Уважаемое сообщество. Свой вопрос по поводу корректной имплементации связи "многие ко многим" я задал на форуме по MS SQL Database Engine на сайте Microsoft. Получил правда только один ответ. Ответ преимущественно в поддержку первого варианта но с замечанием, по поводу дополнительного индекса.

"I would go with #1 generally speaking, but you may want to test the performance change by creating a nonclustered index on your composite primary key and then having a clustered index on the userid column alone. If I recall from past experience correctly, there was a significant enough difference in performance to warrant this change since most of our queries were searching the table on just the userid column. I would have to go back and review some release notes on this to be certain, but the clustered index on the composite key didn't do as good of a job satisfying requests on the user id as a single column clustered index on userid, with a nonclustered unique index on the composite key did. The table was over a ten million rows at the point we saw any difference I believe."

Смотрите тут http://forums.microsoft.com/TechNet/ShowPost.aspx?PostID=2900310&amp;SiteID=17
Re[4]: Как правильно реализовать связь "многие-ко-многим"
От: MasterZiv СССР  
Дата: 26.02.08 13:13
Оценка: +1
1kulibin пишет:

> сейчас вот вспомнил — это однако для упрощения работы с таблицей на

> клиентском приложении — при конкурентном доступе. Т.е. такая ситуация:
> один чел на клиенте получил запись с двойным вашим примари кеем (1,1)
> допустим. пока он тупил другой чел отредактировал его на (2,2). потом
> первый чел говорит серверу, мол update some_table set f1=3, f2=3 where
> *f1=1 and f2=1*. а потом получается что? получается что клиентское

Е-р-у-н-д-а.
Это -- проблема того, что ты разрешаешь модифицировать
первичный ключ. Она всегда будет, независимо от того, составной
он или нет.

> этой id — НИКОГДА не редактируемый пользователем — тогда у нас всё будет


Я не говорил, что PK должен быть модифицируемым нигде, так что — доводы
мимо. PK должен быть всегда немодифицируемым, но это независит от
того, составной он или нет — это несвязанные вещи.
Posted via RSDN NNTP Server 2.1 beta
Re[4]: Как правильно реализовать связь "многие-ко-многим"
От: MasterZiv СССР  
Дата: 26.02.08 13:14
Оценка: +1
ViktorZ пишет:
>
> А какой индекс ещё понадобится?

Надо два, (user,group) и (group,user).
Posted via RSDN NNTP Server 2.1 beta
Re[2]: Как правильно реализовать связь "многие-ко-многим"
От: MasterZiv СССР  
Дата: 26.02.08 13:16
Оценка:
ViktorZ пишет:
> Уважаемое сообщество. Свой вопрос по поводу корректной имплементации
> связи "многие ко многим" я задал на форуме по MS SQL Database Engine на
> сайте Microsoft. Получил правда только один ответ. Ответ преимущественно

Зря ты это сделал. Проблема эта общая, никакой специфики MSSQL тут нет.
Posted via RSDN NNTP Server 2.1 beta
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.