2

我想知道在使用 Yii 和 mysql 表时更好的方法(性能方面)是什么:

  1. 1 个包含所有列的表
  2. 具有外键关系的多个表(在它们之间分布列)

基本上,我要问的是:当一个表有很多关系时,是否会出现性能下降,因为 Yii 会在您进行查询时将所有相应的表提取到对象中?

一个更普遍的问题是:在处理 1 vs 多个表和外键(再次性能..)时,什么是好的做法和更聪明的方法?

4

2 回答 2

3

如果性能是您设计策略中的唯一标准,您会选择 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)
);
于 2012-10-05T07:22:27.370 回答
1

更好的选择是正确地设计符合规范化规则的数据库。以下是一些关于它们的快速链接:

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 使用广泛的延迟加载,并且在您请求并使用它们之前不会加载相关元素。

于 2012-10-05T07:43:41.187 回答