Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Есть ли какая-то best practice для такого случая :
PD>В некоторой таблице должна быть одна и только одна запись.
PD>Например, table institute — запись об институте, название, адрес, реквизиты и т.д. PD>Поскольку речь идет о БД данного института, запись должна быть одна и только одна.
PD>А в нем факультеты, значит table faculty с FK на institute. Ну и прочие таблицы — бухгалтерия, отдел кадров и т.д.
PD>Но эти FK всегда ссылаются на одну и ту же запись в institute, иначе и быть не может. PD>Получается некоторая избыточность. Фактически этот FK есть константа, а зачем тогда он ?
Дикая избыточность — это вообще эта таблица.
К этой таблице ходит какой-то сервис, который предоставляет какой-то API? Если так, то данные об институте — это просто параметры запуска этого сервиса или переменные окружения, где он крутится.
Читая об FK в других таблицах можно сделать вывод, что такая архитектура строится с закладом на расширение (если вдруг появятся какие-то дочерние организации или партнёры). Но тогда непонятно требование "Одна и только одна запись" с последующим запретом добавлять строки.
Что-то вы там мутите.
Похоже на: "или кресик снимите, или трусы оденьте".
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Ну и второй (несколько академический) вопрос. Как запретить создание второй записи в table institute ? Вариант сделать таблицу R/O не годится — первую строку должно быть можно изменять.
Можно установить check constraint
CREATE TABLE Persons (
ID int NOT NULL,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Age int,
City varchar(255),
CONSTRAINT CHK_ID CHECK (ID=1)
);
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Здравствуйте, Stanislaw K, Вы писали:
PD>Я не понимаю, к чему все это. То, что версионность может понадобиться, я не спорю. Вопрос же не в этом, а в том, как быть, если запись именно одна. PD>Если для этого варианта есть соображения — готов их выслушать, а уходить в сторону не буду.
Нет ни чего более не логичней, чем бизнес-логика, "выпрямлять" ее не всегда нужно, а по мне не нужно вообще. Это обычный инвариант, за соблюдение которого отвечает бд.
Есть ли какая-то best practice для такого случая :
В некоторой таблице должна быть одна и только одна запись.
Например, table institute — запись об институте, название, адрес, реквизиты и т.д.
Поскольку речь идет о БД данного института, запись должна быть одна и только одна.
А в нем факультеты, значит table faculty с FK на institute. Ну и прочие таблицы — бухгалтерия, отдел кадров и т.д.
Но эти FK всегда ссылаются на одну и ту же запись в institute, иначе и быть не может.
Получается некоторая избыточность. Фактически этот FK есть константа, а зачем тогда он ?
Ну и второй (несколько академический) вопрос. Как запретить создание второй записи в table institute ? Вариант сделать таблицу R/O не годится — первую строку должно быть можно изменять.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>В некоторой таблице должна быть одна и только одна запись.
PD>Например, table institute — запись об институте, название, адрес, реквизиты и т.д. PD>Поскольку речь идет о БД данного института, запись должна быть одна и только одна.
Если в постановке задачи только одна сущность, то зачем ключи на нее в других таблицах?
Что-то с проектированием не так.
Как вариант решения: можно "развернуть" эту таблицу на 90 градусов.
Сделать два столбца ключ-значение и все реквизиты института хранить в строках, а не в столбцах.
в данном конкретном случае я бы предложил 2 варианта:
1 таблица подразделений института с деревянной структурой где сам институт будет корнем
2 таблица параметров общего вида для всей БД, где будет несколько записей с названием, адресом и т.п.
таблица с единственной записью выглядит неестественно
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Есть ли какая-то best practice для такого случая :
PD>В некоторой таблице должна быть одна и только одна запись.
PD>Например, table institute — запись об институте, название, адрес, реквизиты и т.д. PD>Поскольку речь идет о БД данного института, запись должна быть одна и только одна.
В "идеальном" мире.
В реальном мире записей будет много много, и у каждой записи будет период, в течении которого она валидна.
Здравствуйте, Doom100500, Вы писали:
D>Дикая избыточность — это вообще эта таблица. D>К этой таблице ходит какой-то сервис, который предоставляет какой-то API? Если так, то данные об институте — это просто параметры запуска этого сервиса или переменные окружения, где он крутится.
Сервис ходит к БД Институт. В этой БД данные о самом институте, которые должны храниться в ней, а не в параметрах окружения или тем более параметрах запуска сервиса. И в этой же БД должны храниться данные о факультетах, всяких службах , студентах и т.д.
Почему все эти данные должны быть в БД, а данные о институте в целом в параметрах окружения — решительно не понимаю.
D>Читая об FK в других таблицах можно сделать вывод, что такая архитектура строится с закладом на расширение (если вдруг появятся какие-то дочерние организации или партнёры). Но тогда непонятно требование "Одна и только одна запись" с последующим запретом добавлять строки.
Расширять тут в плане самого института нечего. Новые факультеты или службы могут появиться, старые ликвидироваться, а институт всегда останется один.
Здравствуйте, Stanislaw K, Вы писали:
PD>>Поскольку речь идет о БД данного института, запись должна быть одна и только одна.
SK>В "идеальном" мире.
SK>В реальном мире записей будет много много, и у каждой записи будет период, в течении которого она валидна.
Какой тут к богу идеальный мир! Просто нужно сделать сайт института, а данные хранить в БД. Второго института не будет в этой БД — ему тут делать нечего.
А валидна эта БД будет до тех пор, пока институт существует, то есть неопределенно долгое время.
Здравствуйте, qaz77, Вы писали:
PD>>Поскольку речь идет о БД данного института, запись должна быть одна и только одна.
Q>Если в постановке задачи только одна сущность, то зачем ключи на нее в других таблицах?
Ну вообще-то факультеты и службы принадлежат институту.
Я думал над вариантом без FK. Но тогда получатся таблицы для факультетов, потом групп студентов с FK, аналогично для отделов и подразделений самого института. А вот таблица "institute" окажется сама по себе, на нее никто не ссылается и она ни на кого. Как-то это не нравится.
Q>Что-то с проектированием не так.
Q>Как вариант решения: можно "развернуть" эту таблицу на 90 градусов. Q>Сделать два столбца ключ-значение и все реквизиты института хранить в строках, а не в столбцах.
Да неважно, как хранить. Вопрос о том, как связать с ней остальные таблицы.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>>Поскольку речь идет о БД данного института, запись должна быть одна и только одна. SK>>В "идеальном" мире. SK>>В реальном мире записей будет много много, и у каждой записи будет период, в течении которого она валидна.
PD>Какой тут к богу идеальный мир! Просто нужно сделать сайт института, а данные хранить в БД. Второго института не будет в этой БД — ему тут делать нечего.
При чем тут "второй" институт?
В реальном мире в момент изменения реквизитов "уничтожается" старый институт и на этом месте "создается" другой институт.
PD>А валидна эта БД будет до тех пор, пока институт существует, то есть неопределенно долгое время.
"Неопределенно долгое время", до неопределенного (неизвестного) момента изменения реквизитов, которое может произойти в любой момент.
В современном мире вопрос экономии дискового пространства не стоит, так что пусть в этой таблице хранится сколь угодно много записей, выбирать нужно ту, которая действует в данный период времени.
(а все предыдущие записи хранятся в неизменном виде — запрещен update).
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Получается некоторая избыточность. Фактически этот FK есть константа, а зачем тогда он ?
Чтобы реляционная алгебра работала.
PD>Ну и второй (несколько академический) вопрос. Как запретить создание второй записи в table institute ? Вариант сделать таблицу R/O не годится — первую строку должно быть можно изменять.
Здравствуйте, Stanislaw K, Вы писали:
PD>>Какой тут к богу идеальный мир! Просто нужно сделать сайт института, а данные хранить в БД. Второго института не будет в этой БД — ему тут делать нечего.
SK>При чем тут "второй" институт?
SK>В реальном мире в момент изменения реквизитов "уничтожается" старый институт и на этом месте "создается" другой институт.
Ничего не уничтожается. Сменился адрес — его и меняют, и ничего уничтожать не надо, хватит одного UPDATE
SK>В современном мире вопрос экономии дискового пространства не стоит, так что пусть в этой таблице хранится сколь угодно много записей, выбирать нужно ту, которая действует в данный период времени. SK>(а все предыдущие записи хранятся в неизменном виде — запрещен update).
С какой стати ? Версионность вовсе не требуется. Если ее вводить — это уже иная задача. Да и тогда надо версионность вводить и для факультетов, и для служб, а это совсем иная задача.
Да и не в этом вопрос был. Пусть должна быть СТРОГО одна запись. Это не обсуждается. Как лучше сделать ?
Здравствуйте, Miroff, Вы писали:
PD>>Получается некоторая избыточность. Фактически этот FK есть константа, а зачем тогда он ? M>Чтобы реляционная алгебра работала.
Согласен, но все же получается, что в таблице бесполезное поле и бесполезный FK
Убрать их — не будет выполняться требование РА
Оставить их — бесполезные данные.
Вот в этом-то и вопрос.
PD>>Ну и второй (несколько академический) вопрос. Как запретить создание второй записи в table institute ? Вариант сделать таблицу R/O не годится — первую строку должно быть можно изменять.
M>Триггер на insert сделать, например.
Здравствуйте, Pavel Dvorkin, Вы писали:
SK>>При чем тут "второй" институт? SK>>В реальном мире в момент изменения реквизитов "уничтожается" старый институт и на этом месте "создается" другой институт.
PD>Ничего не уничтожается. Сменился адрес — его и меняют, и ничего уничтожать не надо,
Тем не менее, административно-юридически в большинстве случаев именно это и происходит.
PD>хватит одного UPDATE
А потом, из внешнего мира, придет какой-то документ который ссылается на (старые) реквизиты. получается он будет отклонен, потому что реквизиты, в данный момент, не совпадают?
SK>>В современном мире вопрос экономии дискового пространства не стоит, так что пусть в этой таблице хранится сколь угодно много записей, выбирать нужно ту, которая действует в данный период времени. SK>>(а все предыдущие записи хранятся в неизменном виде — запрещен update).
PD>С какой стати ? Версионность вовсе не требуется.
В реальном мире — требуется. И это значит что ТЗ поставлено не корректно. позже в него будут внесены изменения, из-за которых придется вернуться к этому вопросу (архитектуре сайта, дизайну БД).
PD>Да и не в этом вопрос был. Пусть должна быть СТРОГО одна запись. Это не обсуждается. Как лучше сделать ?
Не заморачиваться на количестве. Брать самую свежую. Предусмотреть удаление "лишних" записей, если они старше 14 дней. Преподнести это как фичу.
Здравствуйте, qaz77, Вы писали:
Q>То, что таблица принадлежит одной БД с другими таблицами, не достаточная связь?
Не уверен. Можно ведь и тотально выбросить все FK. WHERE от этого не пострадает, лишь ссылочная целостность не будет гарантирована, ну так гарантируйте ее на уровне сервиса. Мне один раз довелось в таком унаследованном проекте участвовать. Десятки таблиц и ни одного FK.
И тогда все таблицы будут, естественно, принадлежать одной БД, но, по сути, реляционной такую РБД назвать можно с большими оговорками.
Q>Приведите пример запроса, где FK таблицы института будет использоваться.
Не будут. Точнее , можно, но бессмысленно, так как получится WHERE true
Q>Если отказаться от institute id, то просто не нужно будет писать условие institute.id = faculty.inst_id.
Именно так. Но тогда опять вопрос о связи. В этом-то и проблема.
Я не понимаю, к чему все это. То, что версионность может понадобиться, я не спорю. Вопрос же не в этом, а в том, как быть, если запись именно одна.
Если для этого варианта есть соображения — готов их выслушать, а уходить в сторону не буду.
Здравствуйте, qaz77, Вы писали:
PD>>Можно ведь и тотально выбросить все FK. Q>Я против такого максимализма.
Я тоже отнюдь не за
Q>В одном из проектов у меня в БД была таблица с версией логической структуры этой БД. Q>Вот как такую таблицу связать с другими? И главное зачем?
Незачем. Но она не содержит пользовательских данных. Это просто самописная схема, и ей, конечно, не надо связей.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Не понял. Речь шла о хранении в БД и связях, при чем тут view ? Если в ней данные не будут меняться, то почему бы не использовать вьюху и с ней уже работать как с таблицей?
Сорян, проморгал, что данные могут править.
Здравствуйте, VsevolodC, Вы писали:
VC>1 таблица подразделений института с деревянной структурой где сам институт будет корнем VC>2 таблица параметров общего вида для всей БД, где будет несколько записей с названием, адресом и т.п.
VC>таблица с единственной записью выглядит неестественно
Cогласен, что неестественно, но не очень естественна и ситуация, когда есть таблицы факультетов, групп и т.д., а таблицы института нет, а вместо нее какая-то таблица общего вида...
В качестве бреда, опять же, с вьюхой. Если в ней сделать выборку только одной строки, например по ид, то сколько бы они не вставляли, то всегда будет возвращаться только выбранная. И значения будут меняться только в выбранной, если они, конечно, не полезут менять саму таблицу. Нет?
Здравствуйте, rFLY, Вы писали:
FLY>Здравствуйте, rFLY, Вы писали:
FLY>В качестве бреда, опять же, с вьюхой. Если в ней сделать выборку только одной строки, например по ид, то сколько бы они не вставляли, то всегда будет возвращаться только выбранная. И значения будут меняться только в выбранной, если они, конечно, не полезут менять саму таблицу. Нет?
Вьюха это select. Чтобы поменять данные тебе нужен доступ до таблицы которая под ней.
Здравствуйте, Qt-Coder, Вы писали:
QC>Вьюха это select. Чтобы поменять данные тебе нужен доступ до таблицы которая под ней.
Апдейт вьюхи апдейтит таблицу, которую она использует в качестве источника.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Cогласен, что неестественно, но не очень естественна и ситуация, когда есть таблицы факультетов, групп и т.д., а таблицы института нет, а вместо нее какая-то таблица общего вида...
Забей. Надо -- делай. Встречал такое не раз.
Как ограничить количество записей уже ответили.
Единственное, стоит ли всегда join'ить эту таблицу с другими, или сделать один раз select и запомнить значения полей в приложении?
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>В некоторой таблице должна быть одна и только одна запись. PD>Например, table institute — запись об институте, название, адрес, реквизиты и т.д. PD>Поскольку речь идет о БД данного института, запись должна быть одна и только одна.
Нормальный вариант с одной строкой.
Иначе как сделать запрос "Выведи список студентов, живущих на одной улице с институтом"?
Технологической проблемы нет.
Выходит, это чисто психологическая проблема (принятия нежелательного).
Предлагаю, минуя стадии отрицания, гнева, торга и депрессии, перейти сразу к принятию (факта ненужности FK)
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Есть ли какая-то best practice для такого случая :
PD>В некоторой таблице должна быть одна и только одна запись.
PD>Например, table institute — запись об институте, название, адрес, реквизиты и т.д. PD>Поскольку речь идет о БД данного института, запись должна быть одна и только одна.
PD>А в нем факультеты, значит table faculty с FK на institute. Ну и прочие таблицы — бухгалтерия, отдел кадров и т.д.
PD>Но эти FK всегда ссылаются на одну и ту же запись в institute, иначе и быть не может. PD>Получается некоторая избыточность. Фактически этот FK есть константа, а зачем тогда он ?
PD>Ну и второй (несколько академический) вопрос. Как запретить создание второй записи в table institute ? Вариант сделать таблицу R/O не годится — первую строку должно быть можно изменять.
Сделай тригер который удалёет всё лишнее
А вообще просто писать в строку по фиксированному id
Здравствуйте, kov_serg, Вы писали:
PD>> Ну и второй (несколько академический) вопрос. PD>> Как запретить создание второй записи в table institute ? PD>> Вариант сделать таблицу R/O не годится — первую строку должно быть можно изменять.
_>Сделай тригер который удалёет всё лишнее
Здравствуйте, Qt-Coder, Вы писали:
QC>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>Ну и второй (несколько академический) вопрос. Как запретить создание второй записи в table institute ? Вариант сделать таблицу R/O не годится — первую строку должно быть можно изменять. QC>Можно установить check constraint QC>CREATE TABLE Persons ( QC> ID int NOT NULL, QC> LastName varchar(255) NOT NULL, QC> FirstName varchar(255), QC> Age int, QC> City varchar(255), QC> CONSTRAINT CHK_ID CHECK (ID=1) QC>);
QC>Это запретит создавать записи с ID <> 1
Большинство СУБД требуют уникальности от поля, на которое будет потом установлен foreign key.
Поэтому вот так:
CREATE TABLE Institutes(
ID int not null primary key,
Name varchar(255) NOT NULL,
...,
CONSTRAINT CHK_ID CHECK (ID=1)
);
В будущем, когда всё же потребуется обслуживать несколько институтов, достаточно будет дропнуть 1 констрейнт.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.