1

次の例を検討してください。オンライン書店のDBを構築しているとしましょう。Bookテーブルにはn個のレコードが含まれ、Typeテーブルにはm個のレコードが含まれています。nは非常に大きな数です。mは小さいです。

--------
Book
---------
BookId
BookName
BookType
---------

-------
Type
--------
TypeId
TypeName
---------

これらの2つのテーブルを結合する従来の方法は、BookTypeと呼ばれる3番目のテーブルを作成することです。

---------- 
BookType
---------- 
BookTypeId 
BookId 
TypeId
----------

タイプのある本のレコードを取得する場合は、次のようにします。

select B.*, T.Name from Book B
inner join BookType BT on B.BookId = BT.BookId
inner join Type T on BT.TypeId = T.TypeId

Bookテーブルは非常に大きいため、BookTypeテーブルはさらに大きくなります。DBインデックスはBツリーのようなアルゴリズムを使用しているため、時間コストは2log(n)+Cmになります。右?(BookテーブルとBookTypeテーブルにインデックスが付けられています)

ただし、TypeIdをJSON配列として保存し、それを結合に使用できる場合は、1回のトリップでデータを取得できます。時間はlog(n)+ Cmで、少なくとも2倍の速さです。構文は次のようになります。

select B.*, T.Name from Book B
inner join Type T on ParseJsonAsIntArray(BookType) = T.TypeId

ParseJsonAsIntArray()のようなMySQL関数が見つかりませんでした。なぜ彼らはこれをしないのですか?明らかなことを見逃してしまったらお詫びします。

4

1 に答える 1

2

いいえ、MySQLにJSONを解析するための組み込み関数はありません。最も近いのはExtractValue()XMLデータです。この関数は、Xpath式を使用してXMLドキュメントの要素を選択します。ただし、MySQLでは、XMLやJSONなどの半構造化BLOB内の要素にインデックスを付けることはサポートされていません。それは非効率的なクエリになるはずです。

しかし、まず最初に。非正規化を使用して、実際にはリレーショナルデータベースの利点である問題を解決しようとしています。BookTypeテーブルは長くなりますが、行は個別にかなり小さくなります。ですから、思ったほど悪くはありません。

によるまたはによるBookTypeインデックス付き検索をサポートすることは、大きな利点です。非正規化すると、基本的にこれらのルックアップの1つが効率的になりますが、他のルックアップは犠牲になります。BookType

データベース列にコンマ区切りのリストを格納することは本当に悪いですか?に対する私の答えも参照してください。

于 2012-12-09T23:50:29.483 に答える