我必须维护一个具有许多文本数据类型的列的应用程序,其中插入多个值,用逗号,斜杠或有时甚至管道(|)字符分隔.我想弄明白你为什么要在地球上做这件事.
例如,订单表有一个名为详细信息的列,其中包含以下信息:
2x #ABC-12345 Widget, Black: $24.99 /4x #ABC-12344 Widget, Blue: $23.50
Run Code Online (Sandbox Code Playgroud)
其中/分离的行项目; 有一个VBScript代码,它从记录集中读取值并在一个For循环中解析它,以便使用类似的东西进行显示(这几乎就是代码读取的方式,变量名和所有内容)arydtls = split(rstmp("details"), "/").在整个代码中针对各种表重复该方法.
在我看来,它只是100倍更好(更不用说更容易使用)只是将细节放在一个单独的表中并链接回它(有趣的是,对于Orders它确实这样做,但数据不始终匹配详细信息文本字段,因为OrderDetail表在代码中更新;详细信息字段在应用程序中被视为只读.
我的前任是否知道我没有做过的事情,或者说"WTF?!!"我是对的.当我看这个架构?它看起来像是非常低效且难以维护,并且它使运行报告更加困难,因为我需要的数据可能包含在文本字段中,或者它可能位于十几个具有相似信息的表中并且用于不同的表中部分应用程序.
两种最有可能的情况是:
由于规范化在查询操作方面通常非常昂贵,因此我们有时可以通过消除昂贵的连接并在应用程序端对单行进行操作来获得性能提升.
数据库设计没有绝对的规则,即"在一个行中存储分隔值对于这种情况更好".这一切都是针对您的特定数据集和您的使用模式进行测试,并在必要时进行改进.
根据我的经验,这种模式对标准化的改进并不常见,但这种情况非常不典型.
编辑:第三种可能性是每行具有n值是对原始模式的更改,而不是添加新表,您的前任调整了列的大小.这不一定与"无能"选项有所不同:)但有时候数据库模式更改涉及政治压力......
我的前任是否知道我不知道的事情,或者我说“WTF?!!”是对的吗?当我查看这个架构时?
不,你的前任没有。是的你是对的。不过,请参阅最后的注释。
看起来它的效率极其低下且难以维护,并且它使运行报告变得格外困难,因为我需要的数据可能包含在文本字段中,或者可能位于具有相似信息并用于不同用途的十几个表之一中。应用程序的一部分。
这是极其低效的。不过,请参阅最后的注释。
列应该始终是行不可分割的属性。我在您显示的本列中看到三个(也许四个)属性的两个副本:
2x #ABC-12345 Widget, Black: $24.99 /4x #ABC-12344 Widget, Blue: $23.50
Run Code Online (Sandbox Code Playgroud)
这本来可以更好地设计为:
StockItems
Code char(10) primary key
Desc varchar(50)
Transaction
TxnId something primary key
: : :
TransactionPart
TxnId something \
TxnSeq int / primary key
Quantity integer
Code char(10) foreign key StockItems(Code)
Price float
Run Code Online (Sandbox Code Playgroud)
笔记:
这样做可能是为了在数据库其他地方的值发生变化时保留历史信息。例如,如果库存商品的描述发生更改或该商品被删除。
然而,这仍然不是正确的处理方式。在这种情况下,外键约束将阻止删除项目代码,并且应该制定流程来防止更新描述(例如对库存项目代码进行版本控制)。
当然,如果您永远不会搜索该列中的任何项目,那么这是完全有效的,尽管就未来可能的搜索功能而言是不明智的。
也许在此表中搜索的唯一内容是客户代码 - 那么自由格式的文本字段就足够了。
我仍然不会这样做,但可以提出 YAGNI 论点,如果将来需要添加搜索功能,最好更改数据库模式。
| 归档时间: |
|
| 查看次数: |
1450 次 |
| 最近记录: |