1. ホーム
  2. sql

[解決済み] データベーステーブルのカラムにリストを格納する方法

2022-05-06 19:48:56

質問

だから、あたり 関連する質問に対するMehrdadの回答 , I 得する データベーステーブルのカラムは、リストを格納するものではありません。 むしろ、リストの要素を効果的に保持する別のテーブルを作成し、直接またはジャンクションテーブルを介してそれにリンクする必要があります。 しかし、私が作成したいタイプのリストはユニークなアイテムで構成されます(リンクされた質問の フルーツ の例)。 さらに、リストの項目は明示的にソートされています。つまり、要素を別のテーブルに格納すると、アクセスするたびにソートしなければならないのです。 最後に、リストは基本的にアトミックなもので、リストにアクセスするときはいつでも、その一部ではなく、リスト全体にアクセスしたいと思うでしょうから、リストの一部を集めるためにデータベースクエリーを発行しなければならないのは馬鹿げていると思われます。

AKXの解決策(上記リンク)は、リストをシリアライズして、バイナリカラムに格納することです。 しかし、これもシリアライズとデシリアライズを気にしなければならないので、不便な気がします。

何か良い解決策はないでしょうか? もしあれば では、なぜ? この問題は時々出てくるはずだと思われます。

...私がどこから来たかを知ってもらうために、もう少しだけ情報を提供します。 SQLとデータベース全般を理解し始めるとすぐに、LINQ to SQLに目をつけました。そのため、オブジェクトがどのように照会され、データベースに格納されるかを考えることなく、自分のプログラミングオブジェクトモデルを扱えることを期待して、今は少し甘えてしまっています。

ありがとうございました。

ジョン

UPDATE: 最初の回答で、「CSV/XMLのルートで行くことができます...しかし、しないでください!」とありました。 だから今、私はその理由の説明を探しているのです。 良い参考文献を紹介してください。

また、私が何をしようとしているのか、よりよく理解してもらうために。 私のデータベースには、(x,y)のペアのリストを格納するFunctionテーブルがあります。 (このテーブルには、この議論には関係のない他の情報もあります)。 私は(x,y)のペアのリストの一部を見る必要はないでしょう。 むしろ、私はそれらすべてを取り出して、スクリーン上にプロットするつもりです。 ユーザがノードをドラッグして値を変更したり、プロットに値を追加したりすることができるようにします。

どのように解決するのか?

いいえ、一連の項目を1つの列に格納する、より良い方法はありません。リレーショナル・データベースは、以下のように設計されています。 具体的には 行と列の組み合わせで1つの値を格納する。複数の値を格納するには、以下のようにします。 リストを1つの値にシリアライズして保存し、取り出すときにそれをデシリアライズします。それ以外に方法はありません。(なぜなら、あなたが話しているのは 一般的には、絶対にやってはいけないバッドアイディア ).

そのリストを保存するために別のテーブルを作るのは馬鹿げていると思うのはわかりますが、これはまさにリレーショナル・データベースが行っていることなのです。あなたは苦しい戦いを強いられ、リレーショナル・データベース設計の最も基本的な原則のひとつを意味もなく破っているのです。あなたはSQLを勉強しているところだと言っているので、私なら 強く このような考えは避け、より経験豊富なSQL開発者が推奨するプラクティスに固執することをお勧めします。

あなたが違反している原則は、次のように呼ばれます。 第一正規形 これはデータベースの正規化における最初のステップです。

単純化しすぎかもしれませんが、データベースの正規化とは、データがどのようなものであるかに基づいて、データベースを定義するプロセスです。 そうすれば、賢明で一貫性のあるクエリを作成し、簡単にメンテナンスすることができます。正規化とは、データの論理的な不整合や破損を抑えるためのもので、さまざまなレベルがあります。Wikipediaの データベース正規化 は、実はかなり良い。

基本的に、正規化の最初のルール(または形式)は、テーブルが関係を表すものでなければならないというものです。これは、次のことを意味します。

  • ある行と他の行を区別できるようにする必要があります(言い換えれば、テーブルには できる が主キーとして機能します。これは、行が重複してはいけないということでもあります。
  • データの順序は、行の物理的な順序ではなく、データによって定義されなければなりません(SQLは集合の考えに基づいています。 のみ の順序は、クエリで明示的に定義された順序に依存する必要があります)。
  • すべての行と列の交差点には、1つの で、1つだけ

最後のポイントが、ここで重要なポイントであることは明らかです。SQLはセットを保存するために設計されているのであって、自分でセットを保存するためのバケツを提供するものではありません。そうです、それは可能です。いいえ、世界は終わらないでしょう。しかし、あなたは、SQLとそれに付随するベストプラクティスを理解する上で、すぐにORMを使うことに飛びつくことで、すでに不自由な思いをしています。LINQ to SQLは、グラフ計算機と同じように、素晴らしいものです。しかし、同じように、彼らは ない を知るための代用品として使用することができます。

あなたのリストは現在、完全にアトミックなものかもしれませんし、このプロジェクトで変わることはないかもしれません。しかし、他のプロジェクトでも同じようなことをする習慣がつき、いずれは(おそらくすぐに)、手早く簡単にできるリストインカラムの手法を、まったく不適切な場所に当てはめるシナリオに出くわすことになるでしょう。保存しようとしている内容に適したテーブルを作成するための追加作業はそれほど多くありませんし、他のSQL開発者があなたのデータベース設計を見たときに嘲笑することもありません。さらに、LINQ to SQL はあなたのリレーションを見て、リストに対する適切なオブジェクト指向のインターフェイスを与えてくれるでしょう。 自動的に . なぜ ORM が提供する利便性を捨ててまで、非標準的で不用意なデータベースハッキングを行う必要があるのでしょうか?