2

我试图设计一个尽可能可扩展的数据库,所以我用一个简单的场景来测试这个概念。

假设我有一张contact桌子。联系人通常具有addressphone numbermobile numberemail address

一个表可以保存这些信息。但是,如果联系人有多个这些详细信息中的任何一个怎么办?我的解决方案是像这样使用联结表:

contact -* contact_address *- address
contact -* contact_phone *- phone
contact -* contact_mobile *- phone
contact -* contact_emailaddress *- emailaddress

这将允许我获取有关联系人的所有信息。此外,addressphoneemailaddress成为数据库,服务于从分析到简单重用数据的目的。

但是,我还不知道这对性能有什么影响,以及这是否是一种好的做法,主要是因为该contact表只会容纳 anid而没有其他内容。

需要注意的是,这使用了学说2,使用symfony2,所以编写长查询不会成为问题,我主要关心的是上面的那些,这已经从一张表跳到了八张表,而联系人只是我需要使用类似模式的一个区域这个。

4

3 回答 3

1

这很好用,你完全不用担心。

唯一的问题是您是否允许 Doctrine 延迟加载关系。例子:如果你

$contact = $repository->find(1) ;

稍后在模板中你会做类似的事情

{% for email in contact.emails %}
{{ email.address }}
{% endfor %}

此代码将触发另一个 SELECT 语句。现在,如果您显示每页 10 个联系人,这意味着将执行额外的 10 个查询。

如果您显示地址或电话号码等其他内容,请进行数学计算。

为了避免这种延迟加载,您需要在查询中加入它们。喜欢

// ContactRepository

public function findForSomePage()
{
    return $this->createQueryBuilder("o")
       ->leftJoin("o.addresses", "a")->addSelect("a")
        .... other joins ...
        ->getQuery()
        ->getResult()
}

现在,您需要显示的所有内容都在 1 个查询中获取。

于 2013-05-11T14:17:12.143 回答
0

如果一个联系人有多个地址,您将不会使用联结表,您只需使用地址中的外键来联系联系人。

我预计这种设计很可能会更高效,尽管有很多因素需要考虑。

如果一个地址可以附加到多个联系人,并且一个联系人可以有多个地址,那么您将使用联结表。

于 2013-05-09T10:13:53.090 回答
0

使用表继承。

单表继承示例:

create table address_type(
  id char(1) primary key,
  description text not null unique
);

insert into address_type values
('t', 'Telephone Number'),
('e', 'E-mail Address'),
('m', 'Mailing Address'),
('w', 'Web Address');

create table address_role(
  id char(1) primary key,
  description text not null unique
);

insert into address_role values 
('f','Fax'),
('m','Mobile'),
('h','Home'),
('w', 'Work');

create table address(
  id serial primary key,
  type char(1) not null references address_type(id),
  telephone_number varchar(15) null,
  email_address varchar(320) null,
  web_address varchar(2083) null,
  suite_or_apartment text null,
  city_id bigint null references city(id),
  postal_area_id bigint null references postal_area(id)
);

create table party(
  id serial primary key,
  name varchar(255) not null
);

create table party_address(
  party_id bigint not null references party(id),
  address_id bigint not null references address(id),
  from_date date not null default current_date,
  to_date date null,
  role char(1) null references address_role(id),
  telephone_extension varchar(5) null,
  primary key (party_id, address_id, from_date)
);
于 2013-05-11T19:07:34.367 回答