我想知道在使用 Yii 和 mysql 表时更好的方法(性能方面)是什么:
- 1 个包含所有列的表
- 具有外键关系的多个表(在它们之间分布列)
基本上,我要问的是:当一个表有很多关系时,是否会出现性能下降,因为 Yii 会在您进行查询时将所有相应的表提取到对象中?
一个更普遍的问题是:在处理 1 vs 多个表和外键(再次性能..)时,什么是好的做法和更聪明的方法?
如果性能是您设计策略中的唯一标准,您会选择 1。一个非常糟糕的选择,这会给您在问题的后期阶段带来很多问题。
设计数据库时应考虑到规范化,因此毫无疑问,您必须选择选项 2!
更新
规范化和非规范化的示例:假设我们有一张包含 dvd 出租的表,并且想要跟踪谁租用了 dvd:
平桌:
CREATE TABLE DVD (
DvdId INT NOT NULL AUTO_INCREMENT,
DvdTitle varchar(64),
Rental1 varchar(64),
Rental2 varchar(64),
Rental3 varchar(64),
Primary Key(DvdId)
);
有3个出租条目的空间,之后就有麻烦了。除此之外,当客户的电话号码需要额外字段时,必须额外填写3个字段。
第一步标准化:
CREATE TABLE DVD (
DvdId INT NOT NULL AUTO_INCREMENT,
DvdTitle varchar(64),
Primary Key(DvdId)
);
CREATE TABLE Rentals (
RentalId INT NOT NULL AUTO_INCREMENT,
DvdId INT NOT NULL,
CustomerName varchar(64),
RentalDate DateTime,
Primary Key(RentalId)
);
这更好,但仍未完全标准化。如果客户两次租用同一张 DVD 会怎样。然后在出租表中会有一个双重客户条目。
最终的:
CREATE TABLE DVD (
DvdId INT NOT NULL AUTO_INCREMENT,
DvdTitle varchar(64),
Primary Key(DvdId)
);
CREATE TABLE Rentals (
RentalId INT NOT NULL AUTO_INCREMENT,
DvdId INT NOT NULL,
CustomerId INT NOT NULL,
RentalDate DateTime,
Primary Key(RentalId)
);
CREATE TABLE Customers (
CustomerId INT NOT NULL AUTO_INCREMENT,
CustomerName varchar(64),
Primary Key(CustomerId)
);
更好的选择是正确地设计符合规范化规则的数据库。以下是一些关于它们的快速链接:
http://databases.about.com/od/specificproducts/a/normalization.htm
http://moryadesigns.wordpress.com/2009/09/08/rules-of-data-normalization-sql/
1NF消除重复组——为每组相关属性制作一个单独的表,并为每个表指定一个主键。
2NF消除冗余数据——如果属性仅依赖于多值键的一部分,则将其删除到单独的表中。
3NF消除不依赖于键的列——如果属性对键的描述没有贡献,则将它们删除到单独的表中。
BCNF Boyce-Codd 范式——如果候选键属性之间存在非平凡的依赖关系,请将它们分开到不同的表中。
4NF隔离独立的多重关系——任何表都不能包含两个或多个不直接相关的 1:n 或 n:m 关系。
5NF隔离语义相关的多重关系——可能存在对信息的实际约束,证明分离逻辑相关的多对多关系是合理的。
ONF最优范式 - 仅限于简单(基本)事实的模型,如对象角色模型表示法所示。
DKNF Domain-Key Normal Form – 一个没有任何修改异常的模型。
Yii 使用广泛的延迟加载,并且在您请求并使用它们之前不会加载相关元素。