複雑なデータにアクセス/操作する場合、多くの小さな断片に格納するのが良いのですか、それとも大きなチャンクに格納するのが良いのでしょうか?


11

ギターのタブというかなり複雑なデータを操作するWebアプリを構築しています。

    As a reference, guitar tabs look like this:
Eb|-------------------------------------------------------------------------|
Bb|-------------------------------------------------------------------------|
Gb|--5-5-5-5----------------------------------------------------------------|
Db|--5-5-5-5--3-3-3-3--7-7-7-7--5-5-5-5--2-2-2-2--3-3-3-3--2-2-2-2--5-5-5-5-|
Ab|--3-3-3-3--3-3-3-3--7-7-7-7--5-5-5-5--2-2-2-2--3-3-3-3--2-2-2-2--5-5-5-5-|
Eb|-----------1-1-1-1--5-5-5-5--3-3-3-3--0-0-0-0--1-1-1-1--0-0-0-0--3-3-3-3-|

このデータを大きなチャンクとして保存するか、それを分割して「メモごと」に保存する方が、パフォーマンスにとってより効率的でしょうか?

As a use case:
User changes first chord from:       to:
                         Eb|---   Eb|---
                         Bb|---   Bb|---
                         Gb|--5   Gb|--4
                         Db|--5   Db|--4
                         Ab|--3   Ab|--2
                         Eb|---   Eb|---

ブロックとして保存する場合、タブを操作するコードははるかに複雑になります。メモごとに保存すると、データベースにさらにアクセスする必要があります。どの方法がより効率的ですか?多くのユーザーがデータを変更する可能性があります。最高のパフォーマンスのWebアプリが欲しい回答にまったく影響がある場合は、MySQLを使用します。


2
何のために良い?スペースを節約しますか?CPUパワー?IO?他に何か?
-Oded

まあ、それはウェブアプリです。多くのユーザーは、かなり頻繁にデータを変更する可能性があります。あなたが言及したような多くの要因が異なる影響を与えると思います。私はそれらの詳細にあまり詳しくありません。それが、私がここで尋ねている理由の一部です。
ゲイブウィラード

最適化の対象がわからない場合、どのように回答できますか?事は-特定の問題がある場合は最初にビルドし、次にそれらを整理する方法を尋ねます。
-Oded

12
データベースを構築する前に設計しませんか?私の質問は、データベースの設計です。トラブルシューティングではありません。私はまだデバッグ段階にありません。たとえそうであっても、プログラマではなくStackOverflowに行きます。よくある質問:プログラマーは、アルゴリズムとデータ構造の概念、設計パターン、ソフトウェアアーキテクチャ、ソフトウェアエンジニアリングを扱います...ボトルネックのトラブルシューティングは行いません。
ゲイブウィラード

+1非常に興味深い問題と良い仕事のイラストは有用なユースケースです。ギターのタブアプリを今すぐ開発する良い言い訳があればいいのにと思います。
エヴァンプライス

回答:


8

操作の数はどちらの方法でも同じになります。1つのクエリを実行して曲のすべてのコードを取得し、変更が行われるたびに1つの更新を実行します。実際の違いは、更新のサイズです。ブロック方式では、コードを変更するたびに曲全体を保存する必要があります。個別の方法を使用すると、更新は小さくなり、おそらく全体的にはより効率的になりますが、違いは無視できる場合があります。

考慮すべきもう1つのことは、ノートバイノート方式がより正規化されていることです。つまり、使用すれば、より多くのクエリオプションを今後利用できるようになります。たとえば、初心者は学習する曲を検索するときに知らないコードを除外したり、曲のタイトルがわからない場合はオープニングコードに基づいて検索を許可したりできます。現在これらの機能を計画していない場合でも、後でそのようなものが必要な場合は、データベースを変更するのは非常に苦痛です。


5

一般的に言えば、いくつかの理由により、正規化を増やすことが適切です。

  1. データの重複が少なくなり、物理データベースのサイズが小さくなります。
  2. データの整合性の向上-外部キーを使用して特定の要件を実施できます。
  3. 確認したシンプルな更新コード。
  4. データのサブセットへのより多くのインデックス可能なアクセスルート。

欠点(ここで詳しく説明します)には以下が含まれます。

  1. 正規化はスペースを節約しますが、スペースは安価です。
  2. 正規化は更新を簡素化しますが、読み取りがより一般的です。
  3. 一般的に、スキーマは正規化されていない方がパフォーマンスが向上します。

より正規化された設計から始め、パフォーマンスの問題が発生した場合にのみ非正規化を検討することをお勧めします。


ギターのタブデータベースを使用すると、シンプルさ、一貫性、完全性がパフォーマンスに勝ります。そこで、私が思いつくことができる最も単純な正規化スキーマを使用します。
9000

2

ストレージを操作しやすくし、ねじ込むのに十分なだけハードにします。適度に正規化されたスキーマを使用します。可能であれば、最初のリリースで必要になる以外の使用法を妨げないスキーマを使用してください。

場合は、すべてあなたが必要とするが、特定の曲のタブを表示することで、あなたは一つの文書としてそれらをフェッチする、(MongoDBのような)ドキュメント指向DBに6つの要素の多くを保存することができます。

RDBMSでは、次のようなテーブルに同様に格納します。

table tab_column (
  song_id integer not null foreign key references song(id),
  ordinal integer not null, -- position in the tabulature
  s1 number(2), -- position on 1st string
  ...
  s6 number(2),
  primary key(song_id, ordinal)
)

RDBMSは、歌を表示するために必要なクエリのような単純なクエリが得意です。

select * from tab_column
where song_id = :song_id
order by ordinal;

limitおよびを使用してoffset、曲の一部を表示できます。

後でtab_columnコードを認識できれば、名前付きコードをリストするテーブルに簡単にリンクできます。

これはおそらく可能な限り最も単純なスキーマです。私はそれから始めます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.