質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.51%

  • PostgreSQL

    1357questions

    PostgreSQLはオープンソースのオブジェクトリレーショナルデータベース管理システムです。 Oracle Databaseで使われるPL/SQLを参考に実装されたビルトイン言語で、Windows、 Mac、Linux、UNIX、MSなどいくつものプラットフォームに対応しています。

  • SQLite

    786questions

    SQLiteはリレーショナルデータベース管理システムの1つで、サーバーではなくライブラリとして使用されている。

  • MariaDB

    380questions

    MariaDBは、MySQL派生のオープンソースなリレーショナルデータベースシステムです。 また、MySQLとほぼ同じデータベースエンジンに対応しています。

RDBで1レコードに可変個数のデータが対応するときのUPDATE

解決済

回答 3

投稿

  • 評価
  • クリップ 0
  • VIEW 803

lazex

score 411

1つのレコードに可変個数のデータを持たせるデータの構造なときです。

こんな感じの構造です。

{
  title: "a",
  data: [
    {name: "x"},
    {name: "y"},
    {name: "z"},
  ]
}

これを

table_main
 - id (autoincrement)
 - title

table_sub
 - id (autoincrement)
 - mid (fkey to table_main.id)
 - name

のようなテーブル構造で保存してるとします。

データを

{
  title: "b",
  data: [
    {name: "y"},
    {name: "z2"},
  ]
}


のように変更したときに、 table_sub はどのように更新処理すべきでしょうか。

この場合だと、xがなくなって、yはそのまま、zがz2変更となっています。
こういう情報を更新する時に、SELECT で取ってきたデータと更新するデータとを比較して削除・追加・変更の3パターンに分けてそれぞれ処理するというのは大変です。
なので、普段は table_sub に対して mid で検索して更新対象の mid のデータを全件削除して、新しい登録データを新規に INSERT してます。

data の配列が数千とかあるわけでないなら速度面でも対して気になるものではないのですが、data のような可変個のデータを持つものが4つ、5つとあるような時で、title だけしか変更してないのに全部削除+新規追加ってムダだなーと思いました。

それに、もし table_sub の id に別テーブルから外部キーが設定されていたら、全件削除してとはいかなくなりますし、なにか良い方法はあるのでしょうか。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

checkベストアンサー

0

今の構造だと親データだけが変更されたのか紐付いている子データも変更されているのかの判断が難しい気がしますね…

例えばJSON側で子データが置き換わったことを示す情報(フラグ)などを保持できるなら、
その値をベースに親データのみを更新するなどの制御は可能かと思いますが…。

子データの方は追加・更新・削除については、
個人的には特にパフォーマンス上の問題がなく要件も満たしているなら現行のままDELETE、INSERTで良いと思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/07/31 00:34

    もうしばらく待ってみて、DELETE+INSERTは良くないって回答がなければそうしようかなと思います。
    (table_subに外部キーが必要にならないことを祈って・・・)
    ありがとうございました。

    キャンセル

0

上記のテーブル構成にて、更新を効率よく行う方法として、josnで受け取る情報に
title: "a"は"b"に変わりました。name"x"は削除されました。name"z"は、"z2"に更新されました。
と言う情報をjsonで受け取とる方法が有ります。(jsonにはこだわりませんが)
上記受信jsonの場合は、title"a"のsubメンバー構成を全件削除して、titel"b"に更新してsubをインサートするしか私も考えが浮かびませんでした。

例えば、クライアントのプログラムで表示して更新、削除を行っているとする場合、クライアントでは、この差分情報の作成が可能と思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/07/31 00:33

    idを持たせるなどしてjsonを見るだけで
    ・削除するデータ
    ・更新するデータ
    ・新規追加するデータ
    ・何もしないデータ
    に分けてそれぞれの処理をするということですね
    やはりそうなりますか。

    ありがとうございます。

    キャンセル

0

結論は出てるようですが…
将来的に? table_sub に更新日付を入れよう
なんて話になったら個別にちまちま更新かけるしか
なくなるので、そのへんちょっと心配かなあ。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/07/31 17:14

    更新日時でも変更してない行を消してしまったらだめですね。
    必要になれば編集する側で変更情報を保持させる作りにすることにします。

    キャンセル

同じタグがついた質問を見る

  • PostgreSQL

    1357questions

    PostgreSQLはオープンソースのオブジェクトリレーショナルデータベース管理システムです。 Oracle Databaseで使われるPL/SQLを参考に実装されたビルトイン言語で、Windows、 Mac、Linux、UNIX、MSなどいくつものプラットフォームに対応しています。

  • SQLite

    786questions

    SQLiteはリレーショナルデータベース管理システムの1つで、サーバーではなくライブラリとして使用されている。

  • MariaDB

    380questions

    MariaDBは、MySQL派生のオープンソースなリレーショナルデータベースシステムです。 また、MySQLとほぼ同じデータベースエンジンに対応しています。