Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
设置MySQL表的最有效方法是什么?_Mysql_Database - Fatal编程技术网

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

设置MySQL表的最有效方法是什么?,mysql,database,Mysql,Database,我有一个名为“users”的表,其中包含如下字段 username DOB gender etc username 每个用户都可以将其植物保存在名为“植物”的表中,该表具有以下字段 username plant 因此,用户“johndoe”将在表“plants”上显示如下: johndoe -> lilly johndoe -> orchid1 johndoe -> orchid2 johndoe -> fern1 johndoe -> fern2 问题:

我有一个名为“users”的表,其中包含如下字段

username
DOB
gender
etc
username
每个用户都可以将其植物保存在名为“植物”的表中,该表具有以下字段

username
plant
因此,用户“johndoe”将在表“plants”上显示如下:

johndoe -> lilly
johndoe -> orchid1
johndoe -> orchid2
johndoe -> fern1
johndoe -> fern2
问题:

这是摆桌子的坏方法吗?我这样问是因为当用户数量增加时,会有数百行,其中几行有重复的用户名,因为每个用户可能会有多个植物。这会减缓查询速度吗

如果我为每个用户创建一个plant表,我认为这将大大增加DB请求的数量,并在DB中创建大量的表

另一个选择是为礼来、兰花、蕨类植物等提供单独的桌子,包括

username
DOB
gender
etc
username
但是我仍然会有几行重复的用户名


有什么建议吗?

规范化您的表格。向用户添加id字段,并将该id存储在plants中,而不是用户名中


此外,请阅读更多相关内容,并尝试将其应用于实践。

这是一种非常合理的方式(您最初的建议);这就是我们的目的

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


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

我将使用INT-id来代替用户名。如下所示:

userid
username
DOB
gender
etc
对于你的植物:

plantid
userid_fk
plantname

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

下面是我的方法,并提供了一个示例数据库脚本和查询:

创建/加载用户表-使用代理主键而不是用户名,因为查询会比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
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')
创建植物

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 users(id, username, gender)
  VALUES(1, 'john', NULL)
GO
INSERT INTO users(id, username, gender)
  VALUES(2, 'jane', NULL)
GO
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
结果:

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

(-0.5次nit)您所建议的不是规范化,而是良好的可伸缩性实践。请在评论之前阅读规范表。简单地说,没有两个表可以重复相同的数据。当然,我重复了。他的username/plant表已经是第一个标准格式。如果username是users表的主键,那么这些表将被规范化。规范化不是要有一个ID列。@ravelen:假装你是万能的mysql神是不好的。没有人知道一切,你有什么理由吗?这可能会破坏数据库的正常形式。为什么在plant表中建议将后缀_fk添加到userid?@symcbean以指示它是外键。只是一个指示器,使所有字段更容易阅读。感谢您的详细说明。一个问题:如果我使用与PHP$\u POST绑定的方法,我是否需要发布到所有3个表以保持更新?否-您只需要将记录插入plants\u users表中,您的请求变量应包括plant\u id,您的会话变量应包含user\u id。添加新用户,或者,添加一种新类型的工厂当然需要一个单独的sql查询。