如何在MYSQL列中添加多个项目

3

我目前有一个包括用户名、密码、电子邮件和物品(指游戏中可以收集的物品,也称为“库存”)的表格。但是,如何在物品列中添加多个物品?例如,如果我想在这里添加A、B和C物品:

enter image description here


2
你不想这样做。那是糟糕的数据库设计。 - John Conde
您可以使用JSON格式来编写代码项并将它们保存在一个项目中。 - mohammad mohsenipur
1
您可以将项目存储为JSON,然后在加载时解析JSON等。但是,如果您想按项目查询,则不建议这样做。 - PeppyHeppy
@PeppyHeppy 谢谢,但是如果我使用JSON,我该如何将用户当前收集的项目保存到数据库中? - user1981730
@user1981730,您需要对存储在字段中的JSON进行编码和解码。这不是添加“字段”的最佳方法,但我可能会使用这样的字段来存储不需要在查询中过滤的任意无模式数据。如果您使用PHP(我假设是这样),您可以在此处查看示例:user1981730 http://www.php.net/manual/en/function.json-encode.php - PeppyHeppy
显示剩余2条评论
3个回答

13

你应该使用2个表来存储这些数据。

users: username | password | email
-------------------------
items: username | item

在第二个表格中,您可以为给定的用户名插入无限数量的项目(每个项目是一个新记录)。

您可以按以下方式选择一个用户的所有项目:

SELECT item FROM items WHERE username = ?
你还可以以多种方式将这2张表格组合在一起。
/* this one selects all users who have a specific item */
SELECT u.* FROM users u JOIN items i ON u.username = i.username WHERE i.item = ?

你希望如何使用这些数据?

同时,您应该开始使用ID值(数字),这样您就不必浪费空间重复基于文本的内容,例如用户名。


我认为这可能是一个很好的方法,但是你能给我展示一下每个项目是一个新记录的意思吗?我还是有点困惑。

您可以像这样插入值:

insert into items values ('jonathan', 'hat');
insert into items values ('jonathan', 'drink');
insert into items values ('jonathan', 'mouse');
insert into items values ('user1981730', 'hat');
insert into items values ('user1981730', 'mouse');

这将导致以下结果:

然后,您可以查询所有拥有饮料作为物品的用户:

SELECT u.* FROM users u JOIN items i ON u.username = i.username WHERE i.item = 'drink'

接下来获取 user1981730 所获得的所有物品列表:

SELECT item FROM items WHERE username = 'user1981730'

一旦您满意了,我们可以讨论添加ID列。


什么是ID列?

请注意,在上面的示例中,items表中有很多重复信息。用户名jonathan重复了3次,物品hat重复了两次。如果是真实的数据库,情况会更糟糕。

我们可以通过使用整数ID来表示每个唯一值来节省空间并通常提高性能。每个用户都将具有一个ID,每个唯一物品也是如此。

让我们首先从用户开始。我们必须向用户表中添加新列。

我们将其设置为主键,这将确保所有值都是唯一的,以便没有2个用户可以具有相同的ID。我们还可以使用AUTO_INCREMENT以使该值随着每个新记录自动增加。

然后,我们将更改我们的items表,以便它使用新列而不是用户名。

请注意,我们仍然拥有与之前相同的信息。具有ID号码1的用户拥有饮料、帽子和鼠标,而具有ID号码2的用户则拥有帽子和鼠标。

我们仍然可以执行与以前相同的查询(但要进行一些小的更改)。

/* this selects all the items for a known user_id */
SELECT item FROM items WHERE user_id = ?

/* this selects all the items for a user when we only know the username */
SELECT i.item FROM items i JOIN users u ON u.user_id = i.item_id WHERE u.username = ?

/* this one selects all users who have a specific item */
SELECT u.* FROM users u JOIN items i ON u.user_id = i.user_id WHERE i.item = ?

到目前为止,我们只修改了表格以避免重复用户名。如果我们还想避免重复的物品名称,我们可以添加另一个表格。这开始变得棘手,所以我现在不会详细讨论,但表格结构应如下所示:

users: username | password | email
-------------------------------
items: item_id | name
-------------------------------
users_items: user_id | item_id

用户表保持不变。 物品表有一个新角色,它存储所有唯一的物品。 用户_物品表现在连接其他2个表。


我会在这里结束SO的答案。如果您有任何进一步的问题,可以使用上面列出的地址给我发送电子邮件(在示例表中使用的地址)。


我认为这可能是一种非常好的方式,但是你能展示一下每个项目都是一个新记录的意思吗?我还是有点困惑。 - user1981730
哇!那些编辑太棒了,非常感谢你的帮助! :) 我绝对对此感到满意,嗯,你说的ID列是什么意思? - user1981730
2
这绝对是我在StackOverFlow上收到的最好的答案。这简直让我大开眼界,现在我对所有东西都更加理解了。非常感谢! :) - user1981730

1
为每个项目制作单独的表格行。
INSERT INTO items (userid, item) VALUES
(1, 'item number 1'),
(1, 'item number 2'),
(1, 'item number 3');

不要在用户表中将所有项目放在一行中。JSON、逗号分隔值和其他技术可能听起来很有诱惑力,但它们并不是真正的解决方案。如果您为每个项目保留一个表格,则您的SQL和逻辑将更简单、更清晰。

如果我们这样做,我们的数据库不会变得巨大,即使我们有超过20个字段,那么其中一些字段也是用于大文本的吗? - mohammad mohsenipur
1
数据库可以处理大量信息而不会出现任何问题。它们是专门为此设计的。 - John Conde
假设有几百个用户,每个用户都有大约20-30个项目,这不会有点太多了吗? - user1981730
这根本不是问题。你可以拥有数百万的用户和上千个项目,也不会有任何问题。这就是数据库设计的用途。充分利用它吧!:) - John Conde
哇,我很高兴听到这个消息! :) 另外,这个答案和diolemo在这个问题上的答案是同一件事吗? - user1981730
@user1981730 是的,我的答案是相同的想法。 - diolemo

0

你有几个选项。如果用例足够简单,可以只编码多个值,例如用逗号分隔。

然而,更清晰的方法是使用另一个表,在其中为每个项目创建一个条目,并具有指向第一个表的外键。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接