我正在创建一些用于存储日志条目的数据库表。在正常情况下,我总是会正常化,也不会把价值观放在一起,但我不能百分之百地相信这是个好主意。
我可以恢复正常,并拥有:
LogEntry与LogCategory有多到多的关系,LogEntry与LogEntryProperty有1比多的关系(这是名称/值对)。
Alternative是一个非规范化版本,它只有LogEntry,类别存储为逗号分隔的字符串类别列表,属性存储为逗号限定的名称列表:值格式化的属性。虽然这听起来很难看,但从报告、性能和可搜索性的角度来看,我不确定这是否更好。
哪一个更好?
谢谢。
发布于 2011-07-19 21:33:20
因为只有一个,很少有不同的属性,所以我将远离名称-值对,并为每个属性提供一个具有正确名称和数据类型的单独的表。我使用了通用的Property_,只是为了演示。

这里的问题是,如果一个属性值丢失了,那么确保它不会插入一个值,换句话说,所有的属性值都不是空的。
为了让生活更容易,定义一个视图
create view dbo.vLogs AS
select
LogCategoryName
, LogTime
, p1_Value
, p2_Value
, p3_Value
, p4_Value
, p5_Value
from LogEntry as e
left join Property_1 as p1 on p1.LogEntryId = e.LogEntryId
left join Property_2 as p2 on p2.LogEntryId = e.LogEntryId
left join Property_3 as p3 on p3.LogEntryId = e.LogEntryId
left join Property_4 as p4 on p4.LogEntryId = e.LogEntryId
left join Property_5 as p5 on p5.LogEntryId = e.LogEntryId
left join LogEntryCategory as x on x.LogEntryId = e.LogEntryId
left join LogCategory as c on c.LogCategoryID = x.LogCategoryID此视图(查询)看起来复杂而冗长;但是,如果您尝试下面这样的查询并查看执行计划,您可能会注意到,没有在选择列表中提及的属性表未包含在计划中(未被触及)。
select
LogCategoryName
, LogTime
, p1_Value
, p2_Value
from dbo.vLogs
where LogCategoryName = 'some_category'
and LogTime between from_time and to_time如果你需要像这样简单的东西
select max(p1_Value)
from dbo.vLogs
where LogTime between '2011-07-18' and '2011-07-19'这是执行计划,因为您可以看到只涉及两个表。

这称为表(连接)消除,您确实需要Server、Oracle、PostgreSql 9.x、.要想让它起作用
每次添加属性时,都必须添加一个新表并修改视图。
https://stackoverflow.com/questions/6751934
复制相似问题