1

JSON を MySQL 列に格納することは、保守が困難になり、検索やクエリが容易に行われないという事実から、一般的に「悪い考え」と見なされていることを理解しています。ただし、アプリケーションで遭遇したシナリオは、MySQL テーブルに JSON データを格納するための合理的な使用例だと思います。私は確かに答え、特に私が見落とした可能性のある問題を指摘する可能性のあるもの、または私が計画したことを回避する正当な理由がある場合、およびそうであれば別のアプローチを探しています.

手元にあるアプリケーションは、リソースと在庫の管理を提供し、無数のサブ アセンブリを含む可能性があるアセンブリの構築をサポートします。

名前、SKU、小売価格、寸法など、アイテムのすべてのメタデータを保持するテーブルがあり、この質問で最も重要なのはアイテム タイプです。アイテムは、パーツまたはアセンブリのいずれかです。アセンブリとして定義された項目の場合、その内容は別のテーブルに格納されます。このテーブルの構造は、列を使用して子を親にリンクすることitem_assembly_contentsが想定されています。parent_idご想像のとおり、いつでも、ユーザーはアセンブリにアイテムを追加または削除したり、アセンブリの内容を変更したり、アセンブリを完全に削除したりすることができます。

上記の表の説明を視覚的に表現したものを次に示します。この表には、構成時に別のアセンブリを含むアセンブリを作成するデータが取り込まれています。 アイテムおよびアセンブリ テーブルの構造 上記の構造では、テーブルから削除されたアイテムは、InnoDB を介しitemsてテーブルからも自動的に削除されます。item_assembly_contentsON DELETE CASCADE

以下は JSON 形式のアセンブリの非常に単純な例で、単一のサブ アセンブリ構造を示しています。

{
   "id":1,
   "name":"Fruit Basket",
   "type":"assembly",
   "contents":[
      {
     "id":10,
     "parent_id":1,
     "name":"Apple",
     "type":"part",
     "quantity":1
      },
      {
     "id":11,
     "parent_id":1,
     "name":"Orange",
     "type":"part",
     "quantity":1
      },
      {
     "id":12,
     "parent_id":1,
     "name":"Bag-o-Grapes",
     "type":"assembly",
     "quantity":1,
     "contents":[
        {
           "id":100,
           "parent_id":12,
           "name":"Green Grape",
           "quanity":10,
           "type":"part"
        },
        {
           "id":101,
           "parent_id":12,
           "name":"Purple Grape",
           "quanity":10,
           "type":"part"
        }
     ]
      }
   ]
}

フルーツ バスケットは、「Bag o Grapes」という名前のサブアセンブリを含むアセンブリです。注文と出荷が考慮されるまで、これはすべて素晴らしく機能します。

たとえば、アセンブリを含む出荷を考えてみましょう。ユーザーは、出荷時に定義されたアセンブリの内容をいつでも確認できる必要があります。これらのテーブルは、出荷後に変更されている可能性があるため、テーブルitemsとテーブルからデータを取得することはできません。item_assembly_contents作成した。したがって、アセンブリの内容は出荷とともに明示的に保存して、ユーザーが定義したインベントリ (テーブル)内のアセンブリの状態や単なる存在に関係なく、後で表示できるようにする必要があります。items

出荷内容と一緒にアセンブリ内容を保存するのは少し混乱しますが、JSON でデータを保存することが目に見える解決策であるように思えます。このデータに関する次の点を理解することが重要です。

  1. 検索には使用されませ
  2. UPDATESは単に行の内容を上書きします
  3. ほとんどの場合、クライアントのツリー ビューにデータを入力するために使用されます。これは、変更の必要なく、テーブルに存在する JSON を受け入れます。

データの(できれば)より明確な視覚化については、この画像を参照してください。 現在のテーブル構造と提案されたテーブル構造

質問

  1. これは合理的なユースケースですか?私の懸念は無意味ですか?
  2. 私が見たもので、戻ってきて私を噛む可能性があるものはありますか?
  3. 提案されたスキーマを進めるべきではない理由を説明してもらえますか? もしそうなら....
  4. 別のアプローチを提供できますか?

いつものように、お時間を割いていただき、誠にありがとうございます。ご不明な点や追加情報をお気軽にリクエストしてください。

更新 @Rowland Shawの提案 (以下) に従って、order_assembly_contents テーブルとの再帰的または「ウサギの耳」関係を使用して、別の提案されたテーブル構造を思いつきました。次の画像をご覧ください。 提案されたテーブル構造の更新

データはよりリレーショナルでデータベースに適しているため、JSON を直接保存するよりもはるかに洗練されていると思います。データを取得してクライアント用に作成することも簡単です。上記の構造に関する情報を提供してください。

4

2 に答える 2

1

通常、注文システムの場合、次のようなものを期待します

商品 -< OrderLine > - 注文

あなたの場合、製品に「バニーイヤー」関係を追加して、それ自体を参照できます。だからあなたのoutbound_shipment_contents負けnametype新しいproduct。その後、必要に応じて選択するアイテムのツリーを再帰的に構築できます。

于 2013-09-19T16:06:48.300 に答える
1

これは標準的な部品表の問題のようで、SQL と部品表のパターンに関する優れた記事がたくさんあります。ネイティブ SQL に依存するレポートや詳細な結合機能が非常に複雑になるため、JSON ストレージは避けます。アプリケーションでは、データ アクセス レイヤー内で UI 用の JSON を構築できます。

私見:リレーショナルデータベースでデータをクリーンでアクセスしやすく、リレーショナルに保ち、データアクセス/低レベルのビジネスレイヤーでアプリケーションに転用します。

于 2013-09-19T16:17:37.703 に答える