鉴于用户必须能够在对象上定义自己的字段,并为这些字段定义允许的值 - 即时(无编译) - 如何在不使用EAV的情况下解决这个问题?
示例:所有对象都需要对123 statusnumber(允许1.a或2.b或3.c)的一个或多个引用.
我正在使用EAV进行数据库设计.当我尝试使用具有多个值的属性建模实体时,我遇到了一个问题?
例如
实体
id | name | description
-- | ---- | ------------
1 | configuration1 | configuration1
Run Code Online (Sandbox Code Playgroud)
属性
id | entityId | name | type
-- | -------- | ---- | ----
1 | 1 | att1 | string
2 | 1 | att2 | int
3 | 1 | att3 | List<String> (How will i model this?)
Run Code Online (Sandbox Code Playgroud)
值
id | attributeId | value
-- | ----------- | -----
1 | 1 | a
2 | 2 | 1 …Run Code Online (Sandbox Code Playgroud) 我有2个相关的表:
messages
--------
mid subject
--- -----------------
1 Hello world
2 Bye world
3 The third message
4 Last one
properties
----------
pid mid name value
--- --- ---------------- -----------
1 1 read false
2 1 importance high
3 2 read false
4 2 importance low
5 3 read true
6 3 importance low
7 4 read false
8 4 importance high
Run Code Online (Sandbox Code Playgroud)
我需要从messages使用properties桌面上的标准中获益.例如:如果我有一个像return unread (read=false) high prio (importance=high) messages它应该返回的标准
mid subject
--- -----------------
1 …Run Code Online (Sandbox Code Playgroud) 这个头衔很残酷,但我不知道怎么说.
我有一个绑定到user_id的键值表,用于存储整个站点的用户首选项.如果用户没有进入并更新他们的任何设置,那么每当我要求一个密钥时(比如说"FAVORITE_COLOR"它将为null,所以我需要拉出我与默认用户绑定的默认设置, user_id = 0.
我正在考虑UNION的行,将user_id = 0的结果放到查询的底部,但这只会导致重复.我不确定它是否可能,但我还是喜欢能说出类似的话:
SELECT val FROM k_v WHERE user_id = 123 AND k = 'FAVORITE_COLOR'
UNION IF val IS NULL
SELECT val FROM k_v WHERE user_id = 0 AND k = 'FAVORITE_COLOR';
Run Code Online (Sandbox Code Playgroud)
有什么好办法吗?
编辑:感谢您的所有帮助.如果你的用例只是抓住这个问题的单个值,那么来自dual的NVL正是你想要的,但是如果你打算在同一个查询中返回多个对,那么看一下其他的一些答案,因为他们可能实际上更有意义的实施.
我接下来讨论了ZeissS的建议,因为它很简单,仍然是一个查询,可以使用多个k,v对,并且我没有问题做可能的重复过滤客户端.
在我真正了解它的名字之前,我在许多环境中看到了实体属性值.它的技术经常出现,而不是将数据存储在数据库列中,而是"翻转它",并且有一个包含Entity,Attrbute,Value列和每个数据的表在该表中成为一行.有时它也被称为'Open-Schema'.
对某些事情有好处,对其他事情有害.这篇维基百科文章对其背后的理论进行了很好的讨论.
这似乎是一种经常使用的技术,应该使用Frameworks或Engines或NoSQL数据库或通用软件工具来构建和支持它.
所以,你知道吗?我对Microsoft堆栈(.Net,SQL Server等)以及其他技术堆栈特别感兴趣.
例如,这是一个构建ASP.NET EAV引擎的项目,这正是我正在寻找的,但显然从未开始.
对于Postgres 8.4 DB,我有一个非常完美的关系数据模式,但是我需要能够将任意键/值对与我的几个表相关联,分配的键按行变化.键/值对是用户生成的,因此我无法提前预测它们或纠缠有序的架构更改.
我有以下要求:
我看到以下可能的解决方案:
我担心查询性能,因为我希望有一天会有很多这些.我也关心程序员的表现,因为我必须构建,维护和使用这些东西.这里有明显的最佳方法吗?或者我错过了什么?
postgresql performance database-design key-value entity-attribute-value
我目前正在努力改造我们应用程序的数据系统.基本上,它的设计使人们可以添加他们想要的所有自定义字段,只有几个常量/总是在那里的字段.
我们目前的设计给我们带来了大量的维护问题.我们所做的是动态地(在运行时)为每个字段向数据库添加一列.我们必须有一个元表和其他残余来维护所有这些动态列.
现在我们正在研究EAV,但它似乎并没有好转.基本上,我们有许多不同类型的字段,因此会有一个StringValues,IntegerValues等表...这会让事情变得更糟.
我想知道在数据库中使用JSON或XML blob是否是更好的解决方案,特别是因为在大多数用例中,当我们从这些表中检索任何内容时,我们需要整行.问题是我们需要能够为这些数据创建报告.没有解决方案真正使自定义查询看起来很容易.在报告运行时,搜索这样的blob数据库肯定会成为一场性能噩梦.
每个"行"需要有大约15到100(可能更多)与之关联的属性/列.
我们正在使用SQL Server 2008,我们的应用程序与数据库连接是一个C#Web应用程序(因此,ASP.Net).
你怎么看?完全使用EAV或blob或其他东西?(另外,是的,我知道像MongoDB这样的无架构数据库在这里会很棒,但我不能说服我的老板使用它)
xml sql-server asp.net database-design entity-attribute-value
我开始了一个新的应用程序,现在我正在寻找两条路径,不知道哪种方法可以继续.
我正在构建类似电子商务网站的东西.我有一个类别和子类别.
问题是现场有不同类型的产品,每个产品都有不同的属性.并且网站必须可以通过这些产品属性进行过滤.
这是我最初的数据库设计:
Products{ProductId, Name, ProductCategoryId}
ProductCategories{ProductCategoryId, Name, ParentId}
CategoryProperties{CategoryPropertyId, ProductCategoryId, Name}
ProductPropertyValues{ProductId, CategoryPropertyId, Value}
Run Code Online (Sandbox Code Playgroud)
经过一些分析,我发现这个设计实际上是EAV模型,我读到人们通常不推荐这种设计.
似乎所有东西都需要动态的SQL查询.
这是一种方式,我现在正在看它.
我看到的另一种方式可能被称为很多工作方式,但如果它更好,我想去那里.制作桌子
Product{ProductId, CategoryId, Name, ManufacturerId}
Run Code Online (Sandbox Code Playgroud)
并在数据库中创建表继承,这意味着使表格像
Cpus{ProductId ....}
HardDisks{ProductId ....}
MotherBoards{ProductId ....}
erc. for each product (1 to 1 relation).
Run Code Online (Sandbox Code Playgroud)
我知道这将是一个非常大的数据库和非常大的应用程序域,但它比EAV设计的选项更好,更容易,性能更好.
sql database database-design relational-database entity-attribute-value
我有三个表:components,attributes和attribute_values。每个组件可以具有许多attribute_values。每个attribute_value属于一个属性。是的,这是可怕的EAV模式...
我创建了以下两种形式:
class AttributeValueForm(Form):
attribute = HiddenField()
value = StringField('Value')
class ComponentForm(Form):
... non-related fields left out ...
attribute_values = FieldList(FormField(AttributeValueForm))
Run Code Online (Sandbox Code Playgroud)
这些是SQLAlchemy模型:
class Component(db.Model):
__tablename__ = 'components'
id = db.Column(db.Integer, primary_key=True)
... non-related columns left out ...
class AttributeValue(db.Model):
__tablename__ = 'attribute_values'
id = db.Column(db.Integer, primary_key=True)
value = db.Column(db.String)
attribute_id = db.Column(db.Integer, db.ForeignKey('attributes.id'))
attribute = db.relationship('Attribute', backref='attribute_values'))
component_id = db.Column(db.Integer, db.ForeignKey('components.id'))
component = db.relationship('Component', backref='attribute_values'))
def Attribute(db.Model):
__tablename__ …Run Code Online (Sandbox Code Playgroud) 我正在使用关系数据库(MySQL)和PHP开发库存和仓库管理系统.由于库存产品将具有多种特征(宽度,高度,重量,尺寸,颜色等),因此需要采用数据库模型方法来存储属性以及添加/编辑新属性的可能性,产品类型等.所以,在目前的概念中我只能看到3个可行的模型:
第二个模型的灵感来自于此.
在阅读了很多关于EAV模型的内容之后,我现在对这个模型产生了怀疑,我对如何在订单/发票中连接不同的产品属性等方面几乎没有关注.即使表单的验证似乎也是如此使用EAV模型的真正痛苦,但仍然..我不希望有一个包含100多列的单个表,然后准备好在每次添加新属性时添加新列.
所以,问题是:是否有更便宜的解决方案?或者EAV模型可以改进吗?
我知道这是一个漫长而古老的争论,但每个人都只是指向NoSQL而我只依赖于RDBMS.
编辑:
这些方法(或大多数方法)的缺点是:
到目前为止,唯一可行的解决方案是为每个新类别创建一个新表,并在该表中处理所有自定义属性和规则.但是,再一次,当一个新的类别被建立时,它将最终成为一个真正的痛苦.
编辑2:
在MySQL中使用Json列的选项,并没有从我的角度解决上面提到的任何缺点..或者,也许我错了,我不清楚看到大图..
sql ×4
mysql ×2
sql-server ×2
asp.net ×1
c# ×1
database ×1
flask ×1
frameworks ×1
key-value ×1
oracle ×1
performance ×1
php ×1
postgresql ×1
union ×1
wtforms ×1
xml ×1