日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

SQL反模式:实体-属性-值(EAV)问题(一)

發布時間:2024/1/8 数据库 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SQL反模式:实体-属性-值(EAV)问题(一) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

? ? 但以下關系存在時,可能會將數據設置成為EAV模式,比如一個問題(Issue),可能有繼承它的bug和特性(FeatureRequest),他們的關系如下,引用AntiPatterns

針對上面的關系,如果考慮表格的列可能擴展的情況,設計成EVA(Entity-Atrribute-Value)如下:

CREATE TABLE Issues (issue_id int PRIMARY KEY ); INSERT INTO Issues (issue_id) VALUES (1234); CREATE TABLE IssueAttributes ( issue_id BIGINT NOT NULL, attr_name VARCHAR(100) NOT NULL, attr_value VARCHAR(100), );

通過IssueAttributes表,描述和報告日期通過attribute-value對的方式存儲起來,如下:

INSERT INTO IssueAttributes (issue_id, attr_name, attr_value) VALUES (1234, 'product', '1'), (1234, 'date_reported', '2009-06-01'), (1234, 'status', 'NEW'), (1234, 'description', 'Saving does not work'), (1234, 'reported_by', 'Bill'), (1234, 'version_affected', '1.0'), (1234, 'severity', 'loss of functionality'), (1234, 'priority', 'high');

上面的這種設計,優點在于,如果我想增加一個版本的列,可以直接插入一條記錄即可,不需要增加一列。但是EAV模式,存在如下一些缺點。

1.不能精確定義數據類型,比如date_reported,報告日期,由于各個國家和地區使用日期格式不盡相同,有些是2020-02-02,有些是2/6/2020等等,甚至有些格式無法轉成日期。這樣顯示和統計都會出錯,比如,如下SQL也能插入成功

INSERT INTO IssueAttributes (issue_id, attr_name, attr_value) VALUES (1234, 'date_reported', 'haha'),

2.不能定義約束,使用EVA不能定義外鍵約束;

3.EAV模式中的attribute名稱可能不能統一,比如有些插入的是'date_reported',而有些是'report_date',這樣無法使用SQL查詢;

3.重構查詢結果問題

當我們使用 SELECT * FROM IssueAttributes WHERE issue_id =1234;這樣語句查詢出結果以后,出現了多行,其實我們期望的結果是一行,然后把其他行轉化到列上去,盡管有些SQL已經支持了行轉列了,但是這樣的SQL抬復雜,在不考慮行轉列的情況下,需要如下寫SQL才可以達到一行,查詢多少列就需要關聯自身表多少次,降低了查詢效率。

SELECT i.issue_id, i1.attr_value AS "date_reported", i2.attr_value AS "status", i3.attr_value AS "priority", i4.attr_value AS "description" FROM Issues AS i LEFT OUTER JOIN IssueAttributes AS i1 ON i.issue_id = i1.issue_id AND i1.attr_name = 'date_reported' LEFT OUTER JOIN IssueAttributes AS i2 ON i.issue_id = i2.issue_id AND i2.attr_name = 'status' LEFT OUTER JOIN IssueAttributes AS i3 ON i.issue_id = i3.issue_id AND i3.attr_name = 'priority' LEFT OUTER JOIN IssueAttributes AS i4 ON i.issue_id = i4.issue_id AND i4.attr_name = 'description' WHERE i.issue_id = 1234;

針對以上這些問題,一般設計成EAV模式是想要數據庫更加靈活,但是這種模式更使用NoSQL數據庫,比如使用MongoDB,下一篇文章,我們將介紹針對這種如何設計關系型的解決方案。

?

?

總結

以上是生活随笔為你收集整理的SQL反模式:实体-属性-值(EAV)问题(一)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。