Ваше мнение? - связывание таблиц по LinkTypeId
У меня есть веб-приложение, которое связывает файлы и заметки с клиентами, пользователями, проектами и т. Д. Изначально у меня были таблицы, такие как customerNote, userNote, projectNote... и т. Д.
Особенности дизайна:
1: я не хочу управлять N квадратными таблицами (более 100 таблиц customerNote, userNote, projectNote,... customerFile, projectFile... и т. Д.)
2: я не хочу использовать динамический SQL (TableName от LinkType)
3: я не вижу чистого способа использования таблиц ссылок (без 100+ N квадратов ссылок таблиц)
Теперь у меня есть одна таблица заметок, которая имеет LinkId и LinkTypeId. LinkId, конечно, является PK клиентских |User|Project| и т. Д.; и LinkTypeId указывает на тип ссылки.
Итак, это:SELECT * FROM customerNote WHERE Id = 1210
SELECT * FROM userNote WHERE Id = 3281
Теперь стало так:SELECT * FROM Note WHERE LinkId = 1210 AND LinkTypeId = 2
(2 клиента)SELECT * FROM Note WHERE LinkId = 3281 AND LinkTypeId = 3
(3 пользователь)
Мне нравится простота этого подхода, и я обернул их в функции, которые я вызываю повсюду.
Мои вопросы:
1: без ссылочной целостности, какие проблемы с производительностью или другие проблемы у меня будут?
2: это вызывает проблемы масштабируемости?
3: есть элегантное решение?
Это мой первый пост, и я заранее благодарю всех за помощь.
1 ответ
1: без ссылочной целостности, какие проблемы с производительностью или другие проблемы у меня будут?
У вас могут возникнуть все проблемы, которые должна устранить ссылочная целостность. Вам придется либо справиться с этими проблемами, либо реализовать имитацию всех ограничений ссылочной целостности в коде приложения или с помощью административных процедур (например, отчетов).
Вы также значительно увеличите размер своей таблицы заметок. 100 тысяч строк в каждой из 100 таблиц заметок произвольной формы довольно легко управляемы. Но 10 миллионов строк в одной таблице заметок могут заставить вас пересмотреть, стоит ли жить.
Реализация имитации ограничений целостности в коде приложения означает, что рано или поздно кто-то (возможно, вы) будет обходить стороной приложение и изменять строки с помощью клиента командной строки dbms или клиента графического интерфейса. Вы можете нанести большой урон таким образом. Разумная вещь - сделать контрольную точку или сбросить базу данных, прежде чем идти на такой риск, но 10 миллионов строк заметок снижают вероятность того, что вы это сделаете.
2: это вызывает проблемы масштабируемости?
Оно может. Если у вас есть 100 отдельных таблиц заметок, каждая из них может вырасти до 100000 строк и по-прежнему быстро выполнять запросы. Поместите их все в одну таблицу, и теперь у вас есть 10 миллионов строк. А поскольку они являются заметками, на страницу помещается меньше. Это обычно означает более медленную скорость. При таком дизайне отдельная таблица заметок становится холодной точкой (или горячей точкой, в зависимости от того, как вы на нее смотрите), замедляя каждую таблицу, в которой используются заметки, а не только одну или две сильно аннотированные таблицы.
И после нескольких месяцев жизни на всех столах с более медленной скоростью вы, вероятно, снова разделите эту таблицу монстров на исходные.
3: есть элегантное решение?
Если предполагается, что каждая заметка имеет одинаковую максимальную длину - довольно маловероятное требование для 100 таблиц заметок - тогда создайте домен для заметок и одну таблицу заметок для каждой аннотированной таблицы.
create domain note_text as varchar(1000) not null;
create table user_notes (
user_id integer not null references users (user_id) on delete cascade,
note_timestamp timestamp not null default current_timestamp,
user_note note_text,
primary key (user_id, note_timestamp)
);
Кроме того, вы должны быть очень осторожны, позволяя пользователям аннотировать строки. Они часто (обычно?) Используют столбцы примечаний вместо того, чтобы размещать данные там, где они принадлежат. Например, если у вас есть таблица телефонных номеров пользователей, столбец заметок почти наверняка закончится строкой данных this.
Call 123-456-7890 between 8:00 am and 5:00 pm. (And that will match
none of this user's phone numbers.)
Toll-free orders at 1-800-123-4567.
He eats lunch at McDonald's on Tuesdays.