Здравствуйте, Donz, Вы писали:
_FR>>Я что-то из цитаты вопроса не уловил Можешь из меня процитировать то, что не понятно было?
D>http://www.rsdn.ru/forum/db/3791291.1.aspx
— я вот тут не мог понять, как поможет таблица Attributes. Теперь после еще одного просмотра вроде дошло
_FR>>Это не поможет — я хочу, что целостность заметок поддерживалась самим сервером. В твоём варианте, если я правильно его понимаю, придётся следить за этим самостоятельно. D>Если взять второй вариант, где на каждую новую сущность заводится еще одно поле, то целостность будет гарантироваться на уровне БД, но с суррогатными ключами.
Криво будет гарантирована: сиквел будет думать, что существуют циклы в отношениях (например, Table1 ссылается на Table2).
D>Но после вкуривания задачи у меня появился еще один вариант. Насколько я понял из вышеуказанного поста, количество групп атрибутов заранее определена для каждой сущности. Если это так, и заводить по одному полю на каждую группу в данном проекте нормально, то более правильный вариант таков:
Тут что-то не клеится: поменять местами порядок объявления AttributeLists и Attribute я ещё в уме могу, но вот что значит ссылка на "Attributes" Это ссылка на что из первых двух?
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, _FRED_, Вы писали:
_FR>>>Это не поможет — я хочу, что целостность заметок поддерживалась самим сервером. В твоём варианте, если я правильно его понимаю, придётся следить за этим самостоятельно. D>>Если взять второй вариант, где на каждую новую сущность заводится еще одно поле, то целостность будет гарантироваться на уровне БД, но с суррогатными ключами. _FR>Криво будет гарантирована: сиквел будет думать, что существуют циклы в отношениях (например, Table1 ссылается на Table2).
Что подразумевается под "будет думать"? Он же не строит при запросах полный граф всех связей, или я чего-то не догоняю? При селекте надо будет проверить одну связь. При инсерте столько связей, сколько типов сущностей.
D>>Но после вкуривания задачи у меня появился еще один вариант. Насколько я понял из вышеуказанного поста, количество групп атрибутов заранее определена для каждой сущности. Если это так, и заводить по одному полю на каждую группу в данном проекте нормально, то более правильный вариант таков:
_FR>Тут что-то не клеится: поменять местами порядок объявления AttributeLists и Attribute я ещё в уме могу, но вот что значит ссылка на "Attributes" Это ссылка на что из первых двух?
На AttributeLists. Забыл изменить название в связях.
Здравствуйте, _FRED_, Вы писали:
_FR>Ничего в БД кроме, собственно, таблиц не будет.
О, ну если приложение уже имеет прямой доступ к таблицам, можно вообще не заморачиваться и делать как удобно.
_FR>Обычный UnitOfWork, в рамках которого даже задача "переместить заметку в другой список; удалить сущность и оставшиеся заметки" (если бы понадобилась) не встанет — если нужно, делается в две транзакции никому не мешая.
Не догоняю как бизнес-транзакцию можно разбить на части, не прикручивая DTS на ровном месте.
On 05/04/2010 06:22 PM, _FRED_ wrote: > OS>Может быть функционально разделить эти понятия? > > Неявных связей между таблицами и заметками я как раз пытаюсь избежать.
Неявных не будет. Одна система — Адреса — полностью независима (и ничего
не знает про заметки), а вторая система — Заметки — имеет
документированный способ адресации сущностей из других систем, но от
самих сущностей эта вторая система тоже не зависит.
Есть сущность (в какой-то системе), есть ее "адрес" (для системы
заметок), есть набор заметок для этой сущности и собственно система для
работы с этими заметками.
Пользовательский интерфейс будт работать с двумя системами одновременно.
Address a = addressService.getAddress(?);
NotesList notesList = notesService.getNotesList(createNotesUrl(a));
lblAddress.setText(a.toString());
lblNotesCount.setText(String.valueOf(notesList.getSize()));
public String createNotesUrl(Address a){}
public String createNotesUrl(Address a, String fieldName){}
Здравствуйте, Donz, Вы писали:
D>Здравствуйте, _FRED_, Вы писали:
_FR>>>>Это не поможет — я хочу, что целостность заметок поддерживалась самим сервером. В твоём варианте, если я правильно его понимаю, придётся следить за этим самостоятельно. D>>>Если взять второй вариант, где на каждую новую сущность заводится еще одно поле, то целостность будет гарантироваться на уровне БД, но с суррогатными ключами. _FR>>Криво будет гарантирована: сиквел будет думать, что существуют циклы в отношениях (например, Table1 ссылается на Table2).
D>Что подразумевается под "будет думать"? Он же не строит при запросах полный граф всех связей, или я чего-то не догоняю? При селекте надо будет проверить одну связь. При инсерте столько связей, сколько типов сущностей.
CREATE TABLE Table1 (
Id int PRIMARY KEY,
)
CREATE TABLE Table2 (
Id int PRIMARY KEY,
Table1Id int REFERENCES Table1 (Id),
)
CREATE TABLE Attributes (
Id int PRIMARY KEY,
Table1Id int REFERENCES Table1 (Id),
Table2Id int REFERENCES Table2 (Id),
)
INSERT INTO Table1 VALUES (1)
INSERT INTO Table2 VALUES (1, 1)
INSERT INTO Attributes VALUES (1, 1, NULL)
INSERT INTO Attributes VALUES (2, NULL, 1)
DELETE FROM Table2 WHERE Id = 1
Delete обломится:
The DELETE statement conflicted with the REFERENCE constraint "FK__Attribute__Table__2F10007B". The conflict occurred in database "ZZZ", table "dbo.Attributes", column 'Table2Id'.
D>>>Но после вкуривания задачи у меня появился еще один вариант. Насколько я понял из вышеуказанного поста, количество групп атрибутов заранее определена для каждой сущности. Если это так, и заводить по одному полю на каждую группу в данном проекте нормально, то более правильный вариант таков: _FR>>Тут что-то не клеится: поменять местами порядок объявления AttributeLists и Attribute я ещё в уме могу, но вот что значит ссылка на "Attributes" Это ссылка на что из первых двух? D>На AttributeLists. Забыл изменить название в связях.
Не подходит — нигде не сказано, что Attribute->Name может переиспользоваться. Они вообще уникальны. Например, вместо Name — текст заметки типа text. Тут получается просто просто связь многие-ко-многим между Table1…2 и Attribute. Этого не надо. Нудно многие-к-одному между Attribute и Table1…2.
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, Sinix, Вы писали:
_FR>>Обычный UnitOfWork, в рамках которого даже задача "переместить заметку в другой список; удалить сущность и оставшиеся заметки" (если бы понадобилась) не встанет — если нужно, делается в две транзакции никому не мешая. S>Не догоняю как бизнес-транзакцию можно разбить на части, не прикручивая DTS на ровном месте.
"переместить заметку в другой список" — это изменение двух сущностей (откуда перемещают и куда перемещают). "удалить сущность и оставшиеся заметки" — это изменение первой сущности. Необходимость выполнения обоих операций в одной бизнес-транзакции вызывает сомнения.
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, Other Sam, Вы писали:
OS>On 05/04/2010 06:22 PM, _FRED_ wrote: >> OS>Может быть функционально разделить эти понятия? >> >> Неявных связей между таблицами и заметками я как раз пытаюсь избежать.
OS>Неявных не будет.
Неявная — эта та, целостность которой не может быть обеспечена средствами сервера. Тащить на сервер логику распознования юрл в то время, когда можно обойтись внешними ключами весьма странно. А иных требований (кроме явных связей) я в своей задаче не выдвигал.
Help will always be given at Hogwarts to those who ask for it.
_FR>CREATE TABLE Attributes (
_FR> Id int PRIMARY KEY,
_FR> Table1Id int REFERENCES Table1 (Id),
_FR> Table2Id int REFERENCES Table2 (Id),
_FR>)
_FR>
_FR>Delete обломится:
Согласен.
_FR>Не подходит — нигде не сказано, что Attribute->Name может переиспользоваться. Они вообще уникальны. Например, вместо Name — текст заметки типа text. Тут получается просто просто связь многие-ко-многим между Table1…2 и Attribute. Этого не надо. Нудно многие-к-одному между Attribute и Table1…2.
Как уже писал, если связь многие-к-одному, то зачем вообще дополнительная таблица, содержащая только ID?
Чем не устраивает этот вариант:
Здравствуйте, Donz, Вы писали:
D>Как уже писал, если связь многие-к-одному, то зачем вообще дополнительная таблица, содержащая только ID? D>Чем не устраивает этот вариант:
On 05/04/2010 08:41 PM, _FRED_ wrote: > Неявная — эта та, целостность которой не может быть обеспечена > средствами сервера. Тащить на сервер логику распознования юрл в то > время, когда можно обойтись внешними ключами весьма странно. А иных > требований (кроме явных связей) я в своей задаче не выдвигал.
В проектировании информационных систем есть понятия свзяности и
зацепления. GRASP паттерны проектирования Low Coupling и High Cohesion.
(на всякий случай http://ru.wikipedia.org/wiki/GRASP ).
Вы пытаетесь возложить обязанности по обеспечению целостности данных на
RDBMS. Отлично, делайте таблички связей многие-ко-многим для каждой
сущности у которой должны быть наборы Notes. (Я уже ранее приводил
пример SQL кода).
Я же предлагаю разделить функциональность по двум системам, что позволит
заметно упростить каждую из систем, и в обоих системах целостность
данных будет поддерживаться средствами базы данных, без дополнительных
усилий.
Однако тащить на сервер баз данных логику распознавания URL нет смысла.
Когда вы разделите систему на две части вам не придется в SQL
распознавать URL.
On 05/04/2010 08:38 PM, _FRED_ wrote: > "переместить заметку в другой список" — это изменение двух сущностей > (откуда перемещают и куда перемещают). "удалить сущность и оставшиеся > заметки" — это изменение первой сущности. Необходимость выполнения обоих > операций в одной бизнес-транзакции вызывает сомнения.
Разделяйте на две системы! Что означает "переместить заметку в другой
список" с точки зрения управления адресами? Это что, уточнение адреса,
добавление нового, удаление устаревшего адреса? Нет! Это вообще к
адресам никакого отношения не имеет. Это относится только к заметкам.
Так с какого перепугу вы называете это "изменение двух сущностей" (имея
ввиду изменение двух адресов)?
> Как при создании новой записи в Table1 получать новый ListId? через > SELECT MAX + 1? Чем это лучше лишней таблицы у меня?
АГА! Генерация уникальных ID Смотрите первый пост в ответах в этом
обсуждении (мой пост). > С точки зрения нормального дизайна, я думаю, что не существует. > Скорее всего требовалось обеспечить генерацию уникальных > идентификаторов. В постгриз для этого есть sequense. В других базах > тоже бывает что-то такое.
Здравствуйте, _FRED_, Вы писали:
D>>Как уже писал, если связь многие-к-одному, то зачем вообще дополнительная таблица, содержащая только ID? D>>Чем не устраивает этот вариант: _FR>
_FR>Как при создании новой записи в Table1 получать новый ListId? через SELECT MAX + 1? Чем это лучше лишней таблицы у меня?
А зачем при создании записи получать новый ListId? Насколько я понимаю, надо получить уже существующий, который соответствует данной сущности. Или не так?
Если имелось в виду получение нового ListId при добавлении новой сущности, то это лучше тем, что select max + 1 надо выполнить один раз при добавлении этой сущности (а это, наверное, не так часто случается). А дополнительная таблица с продублированными данными и дополнительной связью (и вся эта структура не совсем очевидна) будет всегда. Она как минимум будет мешать разработчику читать запросы
Если дополнительная таблица все же так необходима, то связь "группа атрибутов-атрибут" лучше перенести в нее. Связь многие-ко-многим очень просто превращается в связь многие-к-одному путем объявления поля AtributId UNIQUE:
Здравствуйте, Other Sam, Вы писали:
>> Как при создании новой записи в Table1 получать новый ListId? через >> SELECT MAX + 1? Чем это лучше лишней таблицы у меня?
OS>АГА! Генерация уникальных ID Смотрите первый пост в ответах в этом OS>обсуждении (мой пост). >> С точки зрения нормального дизайна, я думаю, что не существует. >> Скорее всего требовалось обеспечить генерацию уникальных >> идентификаторов. В постгриз для этого есть sequense. В других базах >> тоже бывает что-то такое.
Извиняюсь, но "слышу звон, но не знаю, где он" — какое отношение мои слова о "SELECT MAX + 1" имеют к "Смотрите первый пост в ответах"?
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, Donz, Вы писали:
D>>>Как уже писал, если связь многие-к-одному, то зачем вообще дополнительная таблица, содержащая только ID? D>>>Чем не устраивает этот вариант:
_FR>>Как при создании новой записи в Table1 получать новый ListId? через SELECT MAX + 1? Чем это лучше лишней таблицы у меня?
D>А зачем при создании записи получать новый ListId? Насколько я понимаю, надо получить уже существующий, который соответствует данной сущности. Или не так?
Покажи, как будет происходить добавление новой строки в Table1.
D>Если имелось в виду получение нового ListId при добавлении новой сущности, то это лучше тем, что select max + 1 надо выполнить один раз при добавлении этой сущности (а это, наверное, не так часто случается). А дополнительная таблица с продублированными данными и дополнительной связью (и вся эта структура не совсем очевидна) будет всегда. Она как минимум будет мешать разработчику читать запросы
Не понимаю, о какой таблице "с продублированными данными и дополнительной связью" речь.
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, _FRED_, Вы писали:
_FR>Покажи, как будет происходить добавление новой строки в Table1.
Возьму вот эту цитату:
Например, есть таблица Заметки { NoteId, Note }, есть таблицы Товары, Служащие, Контракты, Адреса, … всё что угодно. Каждый Товар, Служащий, Контракт или Адрес может иметь несколько Заметок. Всё. Как?
Тогда свои таблицы я бы создал такими:
create table Attrbutes
(
id int4 primary key auto_increment,
name varchar
);
create table Table1
(
id int4 primary key auto_increment,
name varchar,
attr int4 null
);
alter table Table1 add foreign key attr_attr_id (attr) references Attributes(id);
Добавление записей выглядит вот так:
insert into Attributes(name) values ('new attr for new Table1 record');
select max(id) from Attributes;
//Тут куда-нибудь записали этот id
insert into Table1(name, attr) values ('new record', attr_id);
Как-то так.
Можешь в свою очередь написать на скуле свой вариант с добавления записей?
On 05/04/2010 10:37 PM, _FRED_ wrote: > Извиняюсь, но "слышу звон, но не знаю, где он" — какое отношение мои > слова о "SELECT MAX + 1" имеют к "Смотрите первый пост в ответах"?
SELECT MAX + 1 — это ничто иное как генерация уникальных ID. Поскольку
при нескольких одновременных транзакциях MAX + 1 гораздо более
проблемный чем вставка новой записи в таблицу с автоинкрементируемым
полем, то некоторые "проектировщики" решают пользоваться отдельной
таблицей с одним единственным автоинкрементируемым полем.