naetoru2144
@naetoru2144

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

データベースで一つのセルに配列を入れるとまずい?

解決したいこと

データベースで一つのセルに配列を入れるとまずいかどうか知りたい

概要

DjangoでWebアプリを作っています。
SQLite3で名前,誕生日,スコア(30日分)というような項目のデータを管理しようと思っています。

調べたこと

30日分のスコアをそれぞれ名前と誕生日と同列に扱うとやりづらそうだと思い
1つのセルにリストで30日分のスコアを入れようと思いましたが、
検索するとメジャーな方法ではないように見受けられました。
一つのセルにリストを入れられるListCharFieldというフィールドを見つけましたが、検索ヒット数も少なくマイナーなように思われます。

当の質問

・名前,誕生日,スコア(1日目),スコア(2日目)...のように同列に扱うやり方
・名前,誕生日,スコア(30日分のリスト)というように1つのセルに配列を入れるやり方
のどちらがメジャーなのでしょうか…
また、簡単に理由も教えて頂けると有難いですm(_ _)m

またこの他に有効でよく取られる方法がありましたら、検索して勉強しますので名称を教えて頂けないでしょうかm(_ _)m

0

2Answer

DB設計の観点から、1つのセルに配列を入れることは第1正規形を満たさないため、あまり望ましいとは言えません。

第1正規形とは、セルの中身がすべてスカラ値(1つの値)であることを指します。
DB設計や正規形の詳細は以下をご参照ください。

達人に学ぶDB設計 | 正規化と非正規化、インデックスについて - Qiita

さて、解決策ですがスコア用のテーブルを用意すると良いでしょう。

usersテーブル

id name birthday
001 tanaka 2000-01-01
002 suzuki 2000-02-02
003 satou 2000-03-03

scoresテーブル

id day score
001 1 30
001 2 40
002 1 95
003 1 2

このようにテーブルを設計すればiddayがキーになり、「だれ」の「いつ」のscoreが一意に決まります。

あとはSQLでSELECT day, score FROM scores WHERE id="001"などとすれば、ある人のスコアリストが手に入ります。

1Like

Comments

  1. @naetoru2144

    Questioner

    スコア用のテーブルを用意しようと思います。文章や図表が分かりやすくDBの基本的な設計思想を学べるページも提示して頂き非常に助かりました。ありがとうございます。
  2. 私もWebまわりは勉強中なので一緒に頑張りましょう!

以下MySQLのリファレンスでありますが、JSON形式に変換した文字列を、String型(サポートしていればJSON型)カラムに突っ込むというやり方があります
https://dev.mysql.com/doc/refman/8.0/ja/json.html

例えば、{"日付":"点数"}という形式で、{"2021/09/01":"10","2021/09/02":"20"} というような文字列をカラムに保存するというような形です

複数のテーブルを用意する必要がなくシンプルな構成にすることができるメリットがある一方で、「1日の点数だけ知りたい」というときでも全ての日のデータを取得してそこから特定の日の点数を取り出す必要がある、という点で、若干のパフォーマンス低下が予想されますが、データ量が少なかったらさほど問題にはならないと思われます。

これが常に最良な方法というわけではありませんが、こんなやり方もあるんだな、と知っておくとたまに役に立つかもです😇

0Like

Your answer might help someone💌