设置MySQL表的最有效方法是什么?

时间:2011-02-03 14:19:34

标签: mysql database

我有一个名为'users'的表,其中包含

等字段
username
DOB
gender
etc

每个用户都可以将他们的植物保存在名为“植物”的桌子上,该桌子具有以下字段

username
plant

所以用户'johndoe'会在桌面'植物'上显示如下:

johndoe -> lilly
johndoe -> orchid1
johndoe -> orchid2
johndoe -> fern1
johndoe -> fern2

问题:

这是设置表格的一种不好的方法吗?我问,因为当用户数量增长时,将有数百行,其中几行具有重复的用户名,因为每个用户可能有多个工厂。这会减慢查询速度吗?

如果我为每个用户制作一个工厂表,我认为这会大大增加数据库请求的数量,并在数据库中创建大量的表。

另一个选择是为lilly,orchid,fern等提供单独的表格,其中包含

等字段
username

但是我仍然会有几行重复的用户名。

有什么建议吗?

4 个答案:

答案 0 :(得分:2)

规范化你的表格。将id字段添加到用户并将该ID存储在工厂中而不是用户名中。

此外,请阅读有关normalization principles的更多信息,并尝试在实践中应用它们。

答案 1 :(得分:1)

我不会使用用户名来使用INT ID。像这样:

userid
username
DOB
gender
etc

和你的植物:

plantid
userid_fk
plantname

然后加入users.userid = plants.userid_fk以查找匹配项:)

答案 2 :(得分:0)

这是一个非常合理的方式(你的初步建议)来设置;这就是relational databases的用途。

您正在植物表中执行经典多对多关系。每个用户可以拥有多个工厂,每个工厂可能有多个用户。

为了提高效率,您可以使用id来引用您的用户而不是用户名。在大多数关系数据库中,id是行号,是一种非常有效(且紧凑)的引用。

答案 3 :(得分:0)

以下是我如何使用示例数据库脚本和查询:

创建/加载用户表 - 使用代理主键而不是用户名,因为查询对INT的速度更快,可以想象它们会发生变化。

CREATE TABLE users  ( 
    id          int(11) AUTO_INCREMENT NOT NULL,
    username    varchar(255) NOT NULL,
    gender      char(1) NULL,
    PRIMARY KEY(id)
) ENGINE = MyISAM AUTO_INCREMENT = 3

加载用户

INSERT INTO users(id, username, gender)
  VALUES(1, 'john', NULL)
GO
INSERT INTO users(id, username, gender)
  VALUES(2, 'jane', NULL)
GO

创建工厂

CREATE TABLE plants  ( 
    id      int(11) AUTO_INCREMENT NOT NULL,
    name    varchar(200) NOT NULL,
    PRIMARY KEY(id)
) ENGINE = MyISAM AUTO_INCREMENT = 6

加载工厂

INSERT INTO plants(id, name)
  VALUES(1, 'fern1')
GO
INSERT INTO plants(id, name)
  VALUES(2, 'fern2')
GO
INSERT INTO plants(id, name)
  VALUES(3, 'orchid1')
GO
INSERT INTO plants(id, name)
  VALUES(4, 'orchid2')
GO
INSERT INTO plants(id, name)
  VALUES(5, 'lilly1')

创建连接表我在这里使用代理主键,因为很多Web平台无法正确更新具有2列主要连接的连接表。另外,我最终经常在这些类型的连接中添加元数据/细节,没有它就会变得混乱。注意我不限制添加相同植物类型的同一用户的组合,但您可以轻松。

CREATE TABLE plants_users  ( 
    id          int(11) AUTO_INCREMENT NOT NULL,
    plant_id    int(11) NOT NULL,
    user_id     int(11) NOT NULL,
    PRIMARY KEY(id)
)
ENGINE = MyISAM
AUTO_INCREMENT = 8
GO
CREATE INDEX fk_plant_id USING BTREE 
    ON plants_users(plant_id)
GO
CREATE INDEX fk_user_id USING BTREE 
    ON plants_users(user_id)

加载加入表

INSERT INTO plants_users(id, plant_id, user_id)
  VALUES(1, 1, 1)
GO
INSERT INTO plants_users(id, plant_id, user_id)
  VALUES(2, 2, 1)
GO
INSERT INTO plants_users(id, plant_id, user_id)
  VALUES(3, 3, 1)
GO
INSERT INTO plants_users(id, plant_id, user_id)
  VALUES(4, 4, 1)
GO
INSERT INTO plants_users(id, plant_id, user_id)
  VALUES(5, 2, 2)
GO
INSERT INTO plants_users(id, plant_id, user_id)
  VALUES(6, 3, 2)
GO
INSERT INTO plants_users(id, plant_id, user_id)
  VALUES(7, 5, 2)

最终查询:

select
    users.username,
    plants.name
from
    users,plants,plants_users
where
    users.id = plants_users.user_id and
    plants.id = plants_users.plant_id

<强>结果:

    user    name
    john    fern1
    john    fern2
    john    orchid1
    john    orchid2
    jane    fern2
    jane    orchid1
    jane    lilly1