2

我有一个网络应用程序,将文件和注释链接到客户、用户、项目等。最初,我有诸如 customerNote、userNote、projectNote 等表。

设计注意事项:
1:我不想管理 N 个平方表(超过 100 个 customerNote、userNote、projectNote、... customerFile、projectFile...等表)
2:我不想使用动态 SQL(TableName 来自LinkType)
3:我看不到使用链接表的干净方法(没有 100+ N 平方链接表)

现在,我有一个包含 LinkId 和 LinkTypeId 的 Note 表。LinkId当然是client|User|Project|etc表的PK;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:有没有优雅的解决方案?

这是我的第一篇 SO 帖子,我提前感谢大家的帮助。

4

1 回答 1

1

1:如果没有参照完整性,我会有什么性能或其他问题?

您可能会遇到参照完整性旨在消除的所有问题。您将不得不忍受这些问题,或者在应用程序代码中或通过管理过程(如报告)实现对所有参照完整性约束的模仿。

您还将大大增加“注释”表的大小。100 个自由格式注释表中的每一个表中的 10 万行是非常易于管理的。但一张笔记中的 1000 万行可能会让你重新考虑生活是否值得过。

在应用程序代码中实现完整性约束的模拟意味着,迟早会有人(可能是您)绕过应用程序,并通过 dbms 命令行客户端或 gui 客户端更改行。这样你可以造成很大的伤害。明智的做法是在冒这样的风险之前检查点或转储数据库,但是 1000 万行注释使您不太可能这样做。

2:这会导致可扩展性问题吗?

它可以。如果您有 100 个单独的注释表,每个表可以增长到 100,000 行,并且仍然可以快速查询。将它们全部放在一张表中,现在您有 1000 万行。而且因为它们是笔记,所以页面上的内容更少。这通常意味着速度较慢。通过这种设计,单个笔记表变成了一个冷点(或热点,取决于你如何看待它),减慢每个使用笔记的表,而不仅仅是一个或两个重注释的表。

在所有桌子上都以较慢的速度生活了几个月后,您可能会再次将那张怪物桌子拆分为原始桌子。

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)
);

顺便说一句,您需要非常小心地允许用户注释行。他们经常(通常?)使用注释列代替将数据放在它所属的位置。例如,如果您有一个用户电话号码表,那么注释列几乎肯定会以数据行结束。

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.
于 2012-03-07T00:19:07.893 回答