私はまだ学んでいるので、我慢してください。基本的に、抽象的に言えば、1NF または 2NF に簡単に収まるデータのセットがありますが、アイテムの数が異なるものもあり、順序を維持する必要があるレコードに関連付けたいと考えています。注意してください、私は特定のデータベースや言語には関心がありません。この問題に対する非常に基本的なアプローチと理論にすぎません。
最も基本的な要素に単純化するために、目標を完了するために必要な ID、目標、およびタスクがあります。この例では、名前 (文字列)、セクション (文字列) などの他のフィールドは扱いやすいので除外しています。
最初は、データ セットをざっと見ただけで約 2 ~ 3 個のタスク (文字列) が示されているように見えたので、おそらく 5 個のタスクしか存在しないだろうと考えました。私のコードの順序は、1 -> 2 -> 3 などであることが暗示されていました。
ID (key), Goal (string), Task1, Task2, Task3, Task4, Task5
値の半分が NULL になってしまうので、私はすぐにそれが好きではありませんでしたが、ある程度は機能し、スクリプト言語から SQL を呼び出す方法など、他のことを学んでいました。その後、6、7、8 個のタスクを持つ目標が表示されるようになりました。:( 必要に応じてランダムに列を追加し続けて、格納される NULL の割合を増やしますか?いいえ。いい考えではありません。
そこで、すべてのタスクを 1 つのフィールドに詰め込み、区切り記号を指定するだけでよいのでしょうか? 次に、分割と結合または正規表現を使用してデータをフォーマットできます。この例では、私のタスクは の 1 ~ 3 個のトークンで構成されている[A-Za-z ']
ため、処理は簡単です。
ID (key), Goal (string), Tasks (string)
Tasks
フォームはどこですかtask1,task2,task3,...
それについて何かが私を悩ませているようです。同時に複数の目標に取り組んでいて、同じ一連のタスクを適用する必要があるすべての名前のリストを取得したい場合はどうすればよいですか? たとえば、私が持っているとしましょう:
123, "Name1", "Goal1", "task1,task2,task3,task4,task5"
456, "Name2", "Goal2", "task2,task3,task4"
789, "Name3", "Goal3", "task3,task4,task5"
を必要とするすべてのレコードを検索するのは、どれほど厄介なことtask3
でしょうか? たぶん、LIKE を使用して、必要なものを見つけることができますか? 機能の恐ろしい乱用のようです。すべてをバラバラにして、スクリプトでロジックを処理することは、さらに厄介で非効率的で、保守が難しいように見えます。たとえば、すべてのtask3
エントリを変更したり、タスクの順序を変更したりするのはよくありません。
樽で魚を撃ち、まな板で包丁を使うことは、どちらも寿司を作るのに間違いなく使用できます...
そこで、Tasks データを別のテーブルに配置して、同じ ID キーを共有することを考えました。それはこのように見えます。
Main Table
:
123, "Name1", "Goal1"
456, "Name2", "Goal2"
789, "Name3", "Goal3"
Tasks Table
:
123, "Task1"
123, "Task2"
123, "Task3"
123, "Task4"
123, "Task5"
456, "Task2"
456, "Task3"
456, "Task4"
789, "Task3"
789, "Task4"
789, "Task5"
この時点で、私の直感は、私の思考に恐ろしいほどの間違いが生じたということです。秩序を確実に維持する能力を失いました。特定の ID に必要なすべてのタスクのクエリは、任意の順序になる可能性があります。また、多くの冗長データを保存しています。少なくとも私はNULLを取り除きましたか?しかし、それは良くありません。
この時点で、他の何かが私を悩ませています。おそらく、設計の早い段階で対処する必要がありました。しかし、私は自分自身を教えようとしています。それでは、接線を離れて行きます。
これらのタスクの説明は一定であるため、多くの冗長なテキスト データがあります。そのため、スクリプトのオーバーヘッドが多すぎてコードを乱雑にすることなく、ディスクの使用量を最小限に抑え、速度を上げるために、それを最適化する方法を考えていました。私が思いついたアイデアの 1 つは、列挙の表を作成することでした。
Enumerations: ID (key), Task (string)
1, Task5
2, Task4
3, Task3
4, Task2
5, Task1
6, Task10
7, Task9
8, Task8
9, Task7
10, Task6
and so on.
少なくとも、どこにでも格納される文字列の代わりに、はるかに小さい整数を格納できます。それらが最悪の場合の 64 ビット整数であったとしても、それは 8 バイトであり、格納する文字列よりもさらに小さくなります。私のコードは、列挙を読み取り、実行時に格納し、それを使用して文字列を参照します。
それが有効な手法であるかどうか、その問題にアプローチするためのより良い方法があるかどうか、またはそれが何と呼ばれているかさえわかりません。索引付け?それとも違うものですか?それとも、一部のデータベースが自動的に実行できるものですか?
とにかく、主な問題に戻ると、順序に依存するタスクの任意のリストをどうするか? メイン レコードごとに 1 回限りのテーブルを作成し、それぞれに独自の ORDER (キー) とタスク (string/int/enum) エントリを含めますか? オーバーヘッドはさらに悪いようです。
これは基本的な問題であり、それに取り組む標準的な方法がいくつかあるように私には思えます。限られた予算、本の不足、接続の遅さ、そして Google が果てしなく私をどこにも送ってくれなかったので、私は何かヒントを求めようと考えました。知識のソース (特定のサイトまたは記事) への無料のオンライン参照も歓迎します。