web-dev-qa-db-ja.com

あまりにも多くのテーブルをあまりにも多くの列に置き換えますか?

バックグラウンド

デバイスからの数値データをログに記録する小さなMySQLデータベースがあります。各デバイスには最大100個の変数があります。

デバイスのリストは単一のテーブルに保存されます。 deviceIdtype、およびversionがここに保存されます。

データは、data_<deviceId>_<variable>の形式の名前を持つテーブルに格納されます。これらの各テーブルには、基本的に2つのデータが格納されます。timestampと変数value(double型)です。

上記の意味は、新しいデバイスが追加されるたびに、システムが最大100個の新しいテーブルを自動的に作成することを意味します。現在、データベースには数千のMyISAMテーブルがあります。言うまでもなく、これらのテーブルに変更を加えることは難しいです。

簡単にするために、変数が少ない3つのデバイスがあるとします。

  • デバイス1には変数AとBがあります。(デバイスタイプ1、バージョン1)
  • デバイス2には変数AとCがあります。(デバイスタイプ1、バージョン2)
  • デバイス3には変数D、E、およびFがあります。(デバイスタイプ2、バージョン1)

上記のように、データベースには次のテーブルがあります。

devices, with columns (deviceId, type, version)
data_1_A, with columns (timestamp, value)
data_1_B, with columns (timestamp, value)
data_2_A, with columns (timestamp, value)
data_2_B, with columns (timestamp, value)
data_3_D, with columns (timestamp, value)
data_3_E, with columns (timestamp, value)
data_3_F, with columns (timestamp, value)

問題

  • テーブルが多すぎます
  • 新しいテーブルがその場で作成されます

より良い方法

テーブルの数を減らすには、次のことを検討してください。

解決策1:デバイスバージョン固有のテーブル

デバイスタイプごとに一意のテーブルがあります。したがって、テーブルがあります。

devices, with columns (deviceId, type, version)
data_type_1_version_1, with columns (timestamp, deviceId, valueA, valueB)
data_type_1_version_2, with columns (timestamp, deviceId, valueA, valueC)
data_type_2_version_1, with columns (timestamp, deviceId, valueD, valueE, valueF)

問題は、新しいデバイスタイプまたはバージョンが導入されるたびに新しいテーブルを追加する必要があることです。また、各テーブルには異なる列があるため、テーブルから値を読み取る一般的な方法もありません。 動作しません。

解決策2:1一般的な列を持つデータテーブル

devices, with columns (deviceId, type, version, varName1, varName2, varName3, ...)
data, with columns (timestamp, deviceId, value1, value2, value3, ...<enough columns for worst case>)

各値の列に何が含まれているかを理解するには、devicesテーブルを読む必要があります。 動作するはずです。

解決策3:変数情報用の単一のデータ列と追加のテーブル。

devices, with columns (deviceId, type, version)
variables, with columns (varId, deviceId, varName)
data, with columns (timestamp, varId, value)

DBからデータを読み取るには、最初にvarIdテーブルからvariablesを見つけてから、dataテーブルから実際のデータを読み取る必要があります。 動作するはずです。

質問

解決策2は、処理するテーブルが少ないため、3よりも単純に見えます。しかし、ソリューション2を使用すると、それぞれ100列を超える2つのテーブルが作成されます。テーブルが多すぎるという元の問題に対する改善はありますか?

1
user694733

deviceIdvariablesテーブルからdataテーブルに移動する場合、ソリューション3が最適なソリューションです。

1つのデバイスに変数を追加する必要がある場合、ソリューション2のdevicesテーブルとdataテーブルを変更せずにこれを実行できるためです。データをクエリする場合ソリューション2の方法の場合、ソリューション2のdevicesおよびdataテーブルのようなビューを作成できます。

1
Marco

解決策3は魅力的ですが、本質的には「EAV」(キー値)ストアであり、データが大きくなるにつれて不器用で遅くなります。

解決策2は、新しいデバイスタイプ/バージョンが登場し、新しい列が必要になるたびに苦痛になります。

オリジナル (data_<deviceId>_<variable>)データが分散しすぎているため、おそらく悪いです。

だから、私はソリューション1に投票します。

ただし、... SELECTsを見たり、行、デバイス、テーブルなどの数を知らなければ、1年後に必要になる可能性が高いとは言い難いです。

1
Rick James