web-dev-qa-db-ja.com

配列をテーブルに保存

これが私の質問をするのに最適なSEセクションかどうかはわかりません。そうでない場合、私はあなたに親切にあなたに最高のものを見つけるのを手伝ってくれるようお願いします。

PHPとMySqlでWebアプリケーションを開発する配列から大量のデータを保存する方法に疑問があります。

シナリオ

アプリケーションは、世界中のクライアントからテキストメッセージを受信します。クライアントの数は数千に達する場合があります。それぞれが1日に数回、テキストペイロード(json)を含むメッセージを送信します。

Jsonには、クライアント自体を識別するためのいくつかのオブジェクトと、約10個のオブジェクトの配列が含まれています。次に例を示します。

{
    "id_client": "abcdefgh",
    "id_msg": 3245,
    "datetime": "20180308101130",
    "data": [
        { "temp": 20.5 },
        { "humy": 45.1 },
        { "batt": 12.0 },
        { "cnt1": 123456 },
        ...
    ]
}

この情報をデータベースに保存する必要があります。

私の考え

data配列で渡されたディクショナリのキーは、説明、単位などとともに、別のテーブルに格納されます...

最初の3つのフィールド(id_clientid_msgdatetime)は、受信した正確なメッセージを識別するために必要です。したがって、そのようなメッセージを受け取った場合、現在、辞書の各エントリについてテーブルに行を作成します。

+-----------+--------+----------------+------+--------+
| id_client | id_msg |    datetime    | key  | value  |
+-----------+--------+----------------+------+--------+
| abcdefgh  |   3245 | 20180308101130 | temp | 20.5   |
| abcdefgh  |   3245 | 20180308101130 | humy | 40.1   |
| abcdefgh  |   3245 | 20180308101130 | batt | 12.0   |
| abcdefgh  |   3245 | 20180308101130 | cnt1 | 123456 |
+-----------+--------+----------------+------+--------+

これがそのような状況にふさわしいアプローチかどうか疑問に思います。行数が心配です。1日2回、10エントリのメッセージを送信するクライアントが1000ある場合は、次のように追加します。

  • 1000 * 10 * 2 = 1日あたり20.000行
  • 20.000 * 30 =月あたり600.000行
  • 20.000 * 365 = 7.300.000行/年

クエリと統計を作成するために、データは少なくとも年ごとにオンラインである必要があります。

このアプローチはどうですか?この種のアプリケーションにはもっと良いものがありますか?

1
Mark

一貫性の問題につながる可能性のある複数行の共通データを複製しています。これに対処し、データの一貫性と効率を確保するための標準的な方法については、「通常の形式」を参照してください。これについての詳細は データベースの正規化 を読んでください。

重複したデータを分割するには、次のようにします。

                    Message             MessageData
Client              ==============      ================
==============      id_msg    (PK) <--- id_msg (FK) (PK)
id_client (PK) <--- id_client (FK)      key         (PK)
client_name         time_stamp          value
contact_no

ただし、2番目の問題が発生する可能性があります。上記のメッセージデータテーブルは、プロパティバッグまたは Entity-Attribute-Value(EAV)モデル のままですが、柔軟性はさまざまな点で問題になる可能性があります。 EAV構造の長所と短所については、オンライン(ここDBA.SEを含む)と印刷物(Bill Karwinの優れた「SQL Anitpatterns」に関連する章があります)で多くのディスカッションを見つけるので、ここでは詳しく説明しません。

JSONの例でこれらの配列キーが修正されている場合、より適切なレイアウトは次のようになります。

                    Message        
Client              ============== 
==============      id_msg    (PK) 
id_client (PK) <--- id_client (FK) 
client_name         time_stamp     
contact_no          temperature
                    humidity
                    battery
                    cnt1

または、それらのキーがデータ内で共通であるが潜在的に他のキーがあり、anyキー/値のペアを許可する必要がある場合は、次のハイブリッドを使用できます固定列とプロパティバッグ:

                    Message             OtherMessageData
Client              ==============      ================
==============      id_msg    (PK) <--- id_msg (FK) (PK)
id_client (PK) <--- id_client (FK)      key         (PK)
client_name         time_stamp          value
contact_no          temperature
                    humidity
                    battery

年間7.300.000行

適切なテーブルとインデックスの設計では、730万行はそれほど多くありません。

2
David Spillett