Zol*_*aKt 2 mysql sql database database-design denormalization
我有一个db denormalization的设计问题.
我正在建立一个相对较大的数据库,需要尽可能地优化它.
这是一个非常简化的问题模型.
图片中的所有表都是链接的,并且使用规范化的数据库来获取来自特定国家/地区的所有用户,我必须加入所有表.那是cca 250个国家x cca 12000个城市x cca 625000个地区x?地址x?用户......简而言之,这是很多加入,这需要很长时间.
我想要做的是country_id
在user
表中创建冗余,这样我就可以在没有任何连接的情况下获得相同的查询.
问题是,在这种模型中保持一致性的最佳做法是什么(顺便说一句,使用MySql)?
一种方法,也许最快的方法是在插入/更新/删除数据时确保应用程序级别的一致性.
其他是存储过程,我真的看不出任何优点.只有直接调用它们才能确保一致性.如果您想在没有程序的情况下进行一些更改,则一致性会中断.
我一直在研究触发器...不确定如何实现它,以及我将在性能上获得多少.
无论如何,最好确保数据库级别的一致性.
有什么建议?
图片中的所有表都是链接的,并且使用规范化的数据库来获取来自特定国家/地区的所有用户,我必须加入所有表.
您必须加入所有表,因为您使用代理键(ID号),而不是因为表是"规范化"的.使用id号等代理键与规范化无关.
自然键和外键约束是解决问题所需的全部内容.
查看其工作原理的最简单方法是从完整数据开始,然后完全向后工作.假设所有数据都是正确的.
addr_id street street_num region city country
--
1 Babukiaeeva 3a 10000 Zagreb Croatia
2 Riva 16 51000 Rijeka Croatia
3 Andrije Hebranga 2-4 10000 Zagreb Croatia
4 Andrijeviaeeva 2 110000 Zagreb Croatia
Run Code Online (Sandbox Code Playgroud)
要记录"地区'10000'与"克罗地亚"国家/地区'萨格勒布'相关联的事实,请创建一个新表,并从此查询填充该表.
SELECT DISTINCT region, city, country from addresses;
Run Code Online (Sandbox Code Playgroud)
表格看起来像这样.
Table: regions
Primary key: {region, city, country}
region city country
--
10000 Zagreb Croatia
51000 Rijeka Croatia
110000 Zagreb Croatia
Run Code Online (Sandbox Code Playgroud)
然后设置外键引用.
ALTER TABLE addresses
ADD CONSTRAINT FOREIGN KEY (region, city, country)
REFERENCES regions (region, city, country);
Run Code Online (Sandbox Code Playgroud)
要记录"城市'萨格勒布'在国家'克罗地亚'"这样的事实,请创建一个新表,从此查询中填充它.
SELECT DISTINCT city, country from regions;
Run Code Online (Sandbox Code Playgroud)
表格看起来像这样.
Table: cities
Primary key: {city, country}
city country
--
Zagreb Croatia
Rijeka Croatia
Run Code Online (Sandbox Code Playgroud)
然后设置外键引用.
ALTER TABLE regions
ADD CONSTRAINT FOREIGN KEY (city, country)
REFERENCES cities (city, country);
Run Code Online (Sandbox Code Playgroud)
对国家重复.表格国家,城市和地区都是关键,所以他们在5NF.(它们不能具有任何非关键依赖关系,因为它们没有非关键列.)在大区域的上下文中,与整个欧洲一样,地址表也可能是5NF.
它的查询性能条款很可能围绕当前模式运行,因为它不需要连接.
你可能想用ON UPDATE CASCADE
; 但是,您可能不希望级联删除.