4 回答
TA贡献1712条经验 获得超3个赞
在继续您的方法之前,我谨建议您退后一步,考虑您是否真的要将这些数据存储在“键值对”表中。我不知道您的应用程序,但是我的经验表明,每次完成您的工作后,我希望以后创建一个颜色表,织物表和尺寸表。
考虑一下参照完整性约束,如果您采用键值对方法,那么当您尝试在size字段中存储颜色id时,数据库将无法告诉您
考虑一下在具有10个值的表上联接的性能优势,而在多个域中可能有成千上万个值的通用值。关键值索引真的有用吗?
通常,做您正在做的事情的原因是因为域需要是“用户可定义的”。如果是这样,那么即使是我也不会敦促您快速创建表(尽管这是可行的方法)。
但是,如果您的推理是因为您认为它比多个表更易于管理,或者因为您正在设想一个对所有域通用的维护用户界面,那么请停下来并认真思考,然后再继续。
TA贡献1788条经验 获得超4个赞
还有另一个解决方案介于两者之间。您可以使用xml类型列作为键和值。因此,您保留itemid字段,然后有一个xml字段,其中包含为某些键值对定义的xml,<items> <item key="colour" value="red"/><item key="xxx" value="blah"/></items>
然后从数据库中提取数据时,可以用多种不同方式处理xml。取决于您的用法。这是一个可扩展的解决方案。
TA贡献1820条经验 获得超2个赞
在大多数情况下,您将使用第一种方法,这是因为您还没有真正坐下来思考模型。“好吧,我们还不知道键是什么。” 通常,这是相当差的设计。这比实际将您的键作为列要慢得多。
我还要质疑为什么您的ID是varchar。
在极少数情况下,您确实必须实现键/值表,第一种解决方案很好,但是,我通常希望将键保存在单独的表中,这样就不会在键/中存储varchars作为键/值表。
例如,
CREATE TABLE valid_keys (
id NUMBER(10) NOT NULL,
description varchar(32) NOT NULL,
CONSTRAINT pk_valid_keys PRIMARY KEY(id)
);
CREATE TABLE item_values (
item_id NUMBER(10) NOT NULL,
key_id NUMBER(10) NOT NULL,
item_value VARCHAR2(32) NOT NULL,
CONSTRAINT pk_item_values PRIMARY KEY(item_id),
CONSTRAINT fk_item_values_iv FOREIGN KEY (key_id) REFERENCES valid_keys (id)
);
然后,您甚至可以发疯并在按键上添加“ TYPE”,从而进行一些类型检查。
TA贡献1852条经验 获得超7个赞
我曾经在数据库中使用键值对来创建电子表格(用于数据输入),其中出纳员可以通过操作现金抽屉来总结其活动。每对k / v代表一个命名单元,用户在其中输入了金额。这种方法的主要原因是电子表格很容易更改。定期添加新产品和服务(因此出现了新单元)。此外,在某些情况下不需要某些单元格,并且可以将其丢弃。
我编写的应用程序是对应用程序的重写,该应用程序确实将柜员表分为不同的部分,每个部分在不同的表中表示。这里的问题是,随着产品和服务的添加,需要进行模式修改。与所有设计选择一样,与其他设计选择相比,朝着某个方向发展是有利有弊。我的重新设计无疑会降低磁盘速度并更快地消耗磁盘空间。但是,它非常灵活,可以在几分钟内添加新产品和服务。但是,唯一需要注意的问题是磁盘消耗。我没有其他头痛可以回想。
如前所述,我通常考虑使用键值对方法的原因是,用户(可能是企业所有者)希望创建自己的具有用户特定属性集的类型。在这种情况下,我得出以下决定。
如果不需要通过这些属性来检索数据,或者一旦检索到大量数据后就可以将搜索推迟到应用程序,则我建议将所有属性存储在单个文本字段中(使用JSON,YAML,XML等)。 )。如果非常需要通过这些属性来检索数据,则会变得混乱。
您可以创建一个“属性”表(id,item_id,键,值,data_type,sort_value),在此表中,排序列会将实际值覆盖为可按字符串排序的表示形式。(例如,日期:“ 2010-12-25 12:00:00”,数字:“ 0000000001”),也可以按数据类型(例如string_attributes,date_attributes,number_attributes)创建单独的属性表。在这两种方法的众多利弊之间:第一种方法更简单,第二种方法更快。两者都会使您编写难看的复杂查询。
- 4 回答
- 0 关注
- 1132 浏览
添加回答
举报