Ваше мнение? - связывание таблиц по 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.
Другие вопросы по тегам