2016-07-20 3 views
1

データの正規化に関する記事や議論がたくさんあります。ほとんどの場合、人々は正規化するのがかなり難しいと思っていますが、必ずしもそうではありません。ケースバイケースのようですので、私はそのケースについて説明します。それは複雑に見えませんが、私はちょうどエレガントなものを欠いているような気がします。私たちのデータを正規化しないと価値がありますか?

  • は私が検討しているデ - 正規化されたアイデアをサポートする私を与える、または溶液の特定のソリューションや種類で私を指す、または
  • :誰かがどちらかできれば、私は大好きです。

主なことは、ユーザーが検索フィールドにテキストを入力したときに結果に近い検索を行い、結果が非​​常に敏感である必要があることです。しかし、非常に低電力のハードウェア - 私は思う。検索では、個々のアイテム名、バンドル名、および見つかったバンドル内の個々のアイテムのリストを返す必要があります。アイテムとバンドルには多対多の関係がありますが、バンドル内のアイテムの数は限られていますが、そのためには限界があります。

Ex DB: 
[ items ] 
    int: item_id 
    string: name 
    …. 
[ bundles ] 
    int: bundle_id 
    string: bundle_name 
    …. 
[ items_x_bundles ] 
    int: item_id 
    int: bundle_id 

は、与えられたバスケットの組み合わせで10の項目、たとえば、より一般的にこれ以上で、ギフトのバスケット内の食品の異なるバンドルを想像しますが、絶対的な固定制限はありません。新しいバンドルはめったに作成されず、決して変更されません。

など、様々な個々の項目があるとしましょう:

apple, orange, pear, banana, saltines, cheez-its, ritz, 
potato chips, carrots, peas, beans, oreos, gummies, 
hershey bars, coke, gatorade, milk, etc. 

は、そのようにバンドル、:

special : [ apple, saltines, peas, gummies, coke ], 
deluxe: [ pear, carrots, potato chips, oreos ], 
fancy: [ orange, ritz, beans, gummies, milk ], 
mondo: [ banana, pear, saltines, carrots, peas, oreos, coke, milk ] 

"delu" の検索が返されます:

[ deluxe: [ pear, carrots, potato chips, oreos ] 

「appl」を検索すると、返されます。

[ apple ] 
[ special : [ apple, saltines, peas, gummies, coke ] ] 

「ミルク」の検索が返されます:

[ milk ] 
[ fancy: [ orange, ritz, beans, gummies, milk ] 
[ mondo: [banana, pear, saltines, carrots, peas, oreos, coke, milk ] 

我々は完全に正規化されたデータを保持する場合、それはすべての中で、個々の項目のリストを返すために、個々の項目名を見つけるのは簡単だが、はるかに複雑検索文字列を含むバスケット。ここでも低消費電力のIoTハードウェアで動作するため、効率が重要です。それが重要な場合は、sqlite3を使用します。

バンドルを作成するときにBundleテーブルにフィールドを追加することが考えられます。以下のような何か:

[特別]のためのようになります
string: bundle_items 

:これは、はるかに高速/簡単にすべてが冗長性を犠牲にして検索することができます

"apple/saltines/peas/gummies/coke". 

。それは私の "ハック"のように感じますが、私は明らかにエレガントで効率的なソリューションを見ていません。

UPDATE

私はこの1つだけに5つのアップデート/反復を圧縮しています。

おそらく私はこれまでのようにはっきりしていなかったかもしれませんが、パフォーマンスの問題は本質的なものです。低消費電力のIoTグレードのハードウェア、入力された各文字でデータを検索する必要のあるユーザ向けのリアルタイムフィルタ。どのように構造化しても、望みどおりの速さではないでしょう。何らかの遅れがユーザに直接気付かれることもあります。私はハード・ナンバーを持っていません。なぜなら、デベロッパー・マシンでベンチマーク・シミュレーションを実行するのはかなり簡単です。実際のハードウェアではそうではありません。これは、No Matter Whatを逆正規化/最適化する必要があることを意味しますか?おそらく、私は実際にはこれをまだ知っていないので、ここでの質問です。さらに、私が検討している特定の逆正規化方法(上記)に関して憂慮すべき問題があるかどうかは疑問です。

標準化されていないデータをどのようにクエリするのか分かりますが、正規化されたデータに対してスマートで合理的に最適化されたクエリを構成する方法はわかりません。それは私たちの決定を導くのに役立つでしょう。だから:

質問#1)上記の結果を得るために、正規化されたデータのスマート(高速)クエリはどうでしょうか?

質問#2)誰も私が記述した正規化解除方法で目障りな問題を見ていますか?説明されている文脈の中で、それは理にかなっていますか?

カップルが通過した後、Bill Karwinの質問がうまく機能するので、答えは1つです。ありがとうございます。パート2は最終的に別の質問に終わることがあります。

誰かがフォローしている場合、さまざまな種類のクエリの実際の割合の差は、率直に私たちが深く掘り下げて調べる必要があるほど大きく(レコード数によって異なる)それが違うのは驚きではありませんが、その量は驚異的です。不合理な数のレコードではなく、約15xから35,000xを超えています。現実世界に近いかもしれない15倍であっても、私たちは正規化解除に傾いていると思いますが、これはテストするために正常に動作する正規表現を与えました。

+4

非正規化は、パフォーマンスの問題に対処するために使用できる戦略です。あなたはクエリやパフォーマンスの問題について話していないので、あなたが持っているかどうかわからないと仮定しなければなりません。標準化されたデータベース設計には利点があり、データの整合性、保守性などを考慮して設計することが望ましいでしょう。だから、あなたの状況の非正規化についての考え方は、まったく時期尚早です。あなたがこの戦略を考えているかもしれない問題があるかどうか分からないからです。 – scottb

+0

確かに、私は哲学を理解しています、私はこの特定のケースについて疑問に思っています。 (申し訳ありませんが、編集、1分...) –

+0

明らかにコメントを編集するために5分の時間制限があります!私の反応はコメントのために少し長いので、元の質問を更新します。 –

答えて

0

あなたが正規化されたテーブル内のデータを保持する場合は、あなたのようなクエリを実行できます。編集のカップルの後

と、このクエリ(SQLFiddle)をテスト:

SELECT CONCAT(b1.bundle_name, ' : ', GROUP_CONCAT(i1.name)) 
FROM bundles b1 
JOIN items_x_bundles bi1 USING (bundle_id) 
JOIN items i1 USING (item_id) 
WHERE b1.bundle_name LIKE CONCAT('milk', '%') 
GROUP BY b1.bundle_id 
UNION ALL 
SELECT CONCAT(b2.bundle_name, ' : ', GROUP_CONCAT(i2b.name)) 
FROM bundles b2 
JOIN items_x_bundles bi2 ON (b2.bundle_id=bi2.bundle_id) 
JOIN items i2 ON (bi2.item_id=i2.item_id) 
JOIN items_x_bundles bi2b ON (b2.bundle_id=bi2b.bundle_id) 
JOIN items i2b ON (bi2b.item_id=i2b.item_id) 
WHERE i2.name LIKE CONCAT('milk', '%') 
GROUP BY b2.bundle_id 
UNION ALL 
SELECT i3.name 
FROM items i3 
WHERE i3.name LIKE CONCAT('milk', '%') 

あなた?プレースホルダですあなたの検索語を縛るええ、あなたはそれを3回縛らなければならないでしょう。

インデックスをitems(name),bundles(bundle_name),items_x_bundles(item_id,bundle_id)およびitems_x_bundles(bundle_id,item_id)に置く。

次に、EXPLAINを使用して、クエリでインデックスが有効に使用されていることを確認します。

+0

これにはエラーが発生します。うまくいけば、それは私が見ることができない単純なものですが、ここでコメントするには余りにも長いので、上記の質問に情報を追加しました。 –

+0

@ peter.rando、私は上記のクエリでテーブルのエイリアスを修正したと思います。 –

+0

非常に速い応答、ありがとう!私は今夜​​までそれをもう一度試すことができないだろう、あなたはそれがどのように行くかを知らせます。 –

1

コメントが長すぎます。

正規化は、リレーショナルデータベースのデータモデルを設計するときに使用できるツールです。それはかなり強力です。しかし、その元の意図はデータの完全性をサポートすることでした。すべてのデータ項目は、正確に1回、1か所に格納されます。アップデートは一度しか行われないので、アップデートは簡単です。正規化は、データを更新するときに特に重要です。そのため、基礎となるデータモデルは一貫性を維持します。

多くの場合、リレーショナルデータベースは、分析やレポートなどの目的で使用されます。実際、私はしばしば一度作成されたテーブルを何度もクエリします。必要に応じて再作成されます。この場合、正規化は必ずしも役立たない。

データを正規化するかどうか、正規化する方法はアプリケーションによって大きく異なります。私は正規化のサイズに誤差が生じる傾向があります。しかし、データを非正規化する正当な理由がある場合は、主に読み取り専用のアプリケーションでは特に問題ありません。

+0

この応答に感謝します。私があなたの言ったことに同意し、私たちのプロジェクトのためのいくつかの具体的なアドバイスを期待していましたが、それはよく書かれました。司会者は質問が書かれた方法を好まなかったので、私は誰かが特定の助けを提供することをより簡単にしようとしました。 –

関連する問題