在数据建模课程中,我们学习了如何对数据建模。假设一个数据库包括客户、职员、供应商、董事会成员等数据,那么你就需要将所有这些实体抽象到至少一个更高的结构中,这个结构就是人(Persons)。
因为法律定义说企业(Corporation)是一个虚构的人(Person),你可能提供了足够多的字段(比如IsEmployee)来标记任何一个人与组织的关系。任何给定的(实际的或虚构的)人都可以是职员、客户和供应商。在董事会成员的特殊情况下,可以应用法律条文,这一点超出了本文所讨论的范围。
假设在这个 Persons 表中有1,000,000条记录,其中99%的都是客户(Customer)。现在我们假设你的组织有100位职员、500家供应商和15位董事会成员。对此进行建模的一个方法是创建一个 Persons 表,该表包含以下几个比特字段:IsCustomer、IsEmployee、IsVendor和IsMoB。在这些字段中True值的99%都分布在IsCustomer字段,而只有1%的分布到其它字段。
即使你对四个字段都建立索引,这也是一个无意义的做法。如果你决定列出职员(Employees),读取索引基本上很少会起到什么帮助作用。而且,对于其它三个字段的情况,假设少于1%的数据匹配其标准,索引也根本上没有任何作用。另一方面,如果你将 Persons 表分为四个部分,那么你就面临在几个表中更新数据的问题,因为一个人可能是职员、供应商,也可能是客户。
哪种方法都不好。第一种方法从结构方面讲比较好,但是要以牺牲性能为代价。第二种方法性能较高,但是结构不好,而且还需要更新多个表。
比结构不合理更坏的情况是串联问题。假设有一个 Addresses 表,这个表有一个指向 Persons 表的外键,一个指向AddressTypes(home, mailing, business, billing, shipping 等)的外键。如果将 Persons 表根据 Person Types(也就是一个类型一个表)进行划分,那么你就又添加了一层。现在你必须针对每一类 Person 处理 Addresses。职员可能具有地址 A、B 和 C,而同一个人作为供应商则可能具有地址 D、E 和 F。而最坏的情况可能是在 D=A、F=B 而 C<>E 的时候。
对于这类模型我没有一个一成不变的解决方案——每种情况都很不一样。我的建议是考虑你的组织可能发生的情况,并根据具体情况进行建模。
例如,在我最近几年开发的应用程序中,职员与客户的比例非常小——大概比分是500个职员、150000个客户和100家供应商——将他们放在一个表中是没有意义的。对于这样的比例,我找不到把他们放到一个表中的理由。对我来说,将新数据和更新后的数据复制到几个表中更容易,这样我能取得最大的检索性能。
世间没有万能药;我只是根据我的任务提供了我的观点。在你为企业选择任何解决方案之前,要考虑实际的比例和概率,然后根据实际情况对数据库进行建模。而且,要知道你的解决方案并不是能适合所有规模的。