asp.net - 分析场景性能?

标签 asp.net sql database performance database-design

我想设计一些类似于动态表单的东西,管理员可以在其中定义每个表单字段。 我设计了 3 个表:用于共享属性的 mainform 表,然后是将 mainformID 作为外键的 formfield 表,并定义了每个表单字段 例如:

AutoID | FormID  |  FieldName 
_____________________________
100    | Form1   |  weight
101    | Form1   |  height
102    | Form1   |  color
103    | Form2   |  Size
104    | Form2   |  Type
 ....

至少有一个像下面这样的表单值表:

FormFieldID  |  Value  | UniqueResponseID
___________________________________________
100          |   50px   |   200
101          |   60px   |   200
102          |   Red    |   200

100          |   30px   |   201
101          |   20px   |   201
102          |   Black  |   201


103          |   20x10  |   201
104          |    Y     |   201
....

对于每个表单,我必须加入这 3 个表以捕获所有字段和值。我想知道它是否是设计这种场景的唯一方法?它会降低sql性能吗?或者有什么更快更好的方法吗?

最佳答案

这是 EAV 的一种形式,我假设您绝对必须这样做,而不是“静态”设计。

does it decrease sql performance?

是的,获取一堆行(在 EAV 下)总是比只获取一行(在静态设计下)慢。

or is there any fast and better way?

不是从逻辑的角度来看,而是可以在物理层面进行重大优化(至少对于查询性能而言)。具体来说,您可以仔细设计 key 以最大程度地减少 I/O(通过将相关数据放在一起),甚至消除 JOIN 本身。

例如:

enter image description here

此模型通过 FOREIGN KEY 层次结构一直向下迁移到 ATTRIBUTE_VALUE 表。 ATTRIBUTE_VALUE 表中生成的自然组合键使我们能够:

  • 通过单个索引范围扫描 + 表堆访问获取给定形式的所有属性1 em> 在 ATTRIBUTE_VALUE 表上,并且根本不执行任何 JOIN。除此之外,您还可以 cluster 2 它消除了表堆访问,只剩下索引范围扫描3

  • 如果您只需要获取特定响应的数据,请更改复合键中字段的顺序,使 RESPONSE_ID 位于前沿。

  • 如果您需要同时“按表单”和“按响应”查询,您将需要两个索引,在这一点上,我建议二级索引也为 cover 4 VALUE 字段。

例如:

-- Since we haven't used NONCLUSTERED clause, this is a B-tree
-- that covers all fields. Table heap doesn't exist.
CREATE TABLE ATTRIBUTE_VALUE (
    FORM_ID INT,
    ATTRIBUTE_NAME VARCHAR(50),
    RESPONSE_ID INT,
    VALUE VARCHAR(50),
    PRIMARY KEY (FORM_ID, ATTRIBUTE_NAME, RESPONSE_ID)
    -- FOREIGN KEYs omitted for brevity.
);

-- We have included VALUE, so this B-tree covers all fields as well.
CREATE UNIQUE INDEX ATTRIBUTE_VALUE_IE1 ON
    ATTRIBUTE_VALUE (RESPONSE_ID, FORM_ID, ATTRIBUTE_NAME)
    INCLUDE (VALUE);

1 或特定属性,或特定属性的特定响应。

2 除非您指定 NONCLUSTERED 子句,否则 MS SQL Server 默认对所有表进行集群。

3 对集群的友好性和 JOIN 的消除是自然键(相对于代理键)的一些主要优势。但它们也使表“更胖”并且不会与 ON UPDATE CASCADE 隔离。我相信在这种特殊情况下利大于弊。有关自然键与代理键的更多信息,请查看 here .

4 幸运的是,MS SQL Server supports仅出于覆盖目的在索引中包含字段(而不是实际搜索索引)。这使得索引比相同字段上的“正常”索引更精简。

关于asp.net - 分析场景性能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20934239/

相关文章:

c# - ASP.NET 学习路径

sql - 删除重复项后面的行

database - 为 SEO 友好的 URL 优化数据库

c# - DateTime.Now.ToUniversalTime() 年份错误

c# - 如何更改下拉列表项的子字符串的颜色

php - mysql更新子句被忽略

sql - 获取时间跨度内的 session 持续时间平均值

php - 使用php在数据库mysql中上传图像

php - 验证预约表

c# - 在 C# 中重命名文件并排除文件的扩展名