私は現在、人のユーザー名、パスワード、電子メール、およびアイテムを含むテーブルを持っています (アイテムとは、「インベントリ」とも呼ばれるゲームで収集できるアイテムのようなものです)。しかし、アイテム列に複数のアイテムを追加するにはどうすればよいですか? たとえば、アイテム A、B、および C をここに追加したい場合:
3 に答える
このデータを格納するには、2 つのテーブルを使用する必要があります。
users: username | password | email
-------------------------
items: username | item
次に、2 番目のテーブルに特定のユーザー名の項目を無制限に挿入できます (各項目は新しいレコードです)。
次に、次のように 1 人のユーザーのすべての項目を選択できます。
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は 2 回繰り返されます。これは、実際のデータベースではさらに悪化します。
整数 ID を使用してそれぞれの一意の値を表すことにより、スペースを節約し、一般的にパフォーマンスを向上させることができます。各ユーザーには ID があり、各固有のアイテムにも ID があります。
ユーザーだけから始めましょう。users テーブルに新しい列を追加する必要があります。
2 人のユーザーが同じ ID を持つことができないように、すべての値が一意であることを保証する PRIMARY KEY にします。AUTO_INCREMENTを使用して、新しいレコードごとに値を自動的に増加させることもできます。
次に、項目テーブルを変更して、ユーザー名の代わりに新しい列を使用するようにします。
以前と同じ情報がまだ残っていることに注目してください。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
usersテーブルは以前と同じです。itemsテーブルには新しい役割があり、すべての一意のアイテムが格納されます。users_itemsテーブルは、他の 2 つのテーブルにリンクするようになりました。
ここでSOの回答を終了します。さらに質問がある場合は、上記のアドレス (例の表で使用されているアドレス) にメールでお問い合わせください。
個別の表に項目ごとに行を作成します。
INSERT INTO items (userid, item) VALUES
(1, 'item number 1'),
(1, 'item number 2'),
(1, 'item number 3');
ユーザー テーブルの 1 行にすべての項目を配置しないでください。JSON、コンマ区切り値、およびその他の手法は魅力的に聞こえるかもしれませんが、実際のソリューションではありません。それらを追跡する専用のテーブルに項目ごとに 1 つの行がある場合、SQL とロジックははるかに単純でクリーンになります。
いくつかのオプションがあります。どちらか (ユース ケースが十分に単純な場合) は、複数の値をコンマで区切るなどしてエンコードするだけです。
ただし、クリーンなアプローチは、アイテムごとに 1 つのエントリを作成し、最初のテーブルを指す外部キーを持つ別のテーブルを使用することです。