1

速度と履歴の維持を目的として、挿入専用テーブルを作成しました。その構造は非常に一般的であり、次のとおりです。

  `id` bigint(20) unsigned NOT NULL auto_increment,
  `user_id` bigint(20) unsigned NOT NULL,
  `property` varchar(32) NOT NULL,
  `value` longblob NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;

これは、user_idが割り当てられた単純なKey/Valueテーブルです。このアプローチには、すべてのユーザーが同じプロパティを持っているわけではないため、テーブルでフィールドが無駄にならないという利点があります。また、ユーザーがこれまでに行った特定のプロパティへのすべての変更を確認できるため、変更のローリングログが可能になります。

これで、このテーブルで削除や更新が発生することはないため、最大のIDは常に最新のエントリであると想定できます。

ただし、「address1」、「address2」、「city」、「state」など、一度に複数のプロパティを選択したいので、それぞれを最も高いIDを持つタイプのエントリにします。

したがって、「state」プロパティを8回、「city」プロパティを4回変更した場合は、SELECTでそれぞれの最新(1つの州と1つの都市)のみを返します。

このタイプのテーブルでこれを効率的に実行できるかどうかはわかりません。そのため、さまざまなテーブルアプローチを利用できます。

これ以上情報を作成する必要がある場合、または質問をより明確にする必要がある場合は、お知らせください。

===以下を試しましたが、最後の「address2」の変更後に3行の「address1」の変更が発生する可能性があります。おそらく、GROUP BYを使用すると機能しますか?

SELECT property, value FROM kvtable WHERE user_id = 1 AND (property = 'address1' OR property = 'address2') ORDER BY id

4

1 に答える 1

4

IDが増分整数であり、手動で順不同で指定していないMAX()と仮定すると、サブクエリ内のいくつかの集計を使用してこれを行うことができます。サブクエリのポイントは、プロパティ名ごと、ユーザーごとに最新のエントリを返すことです。これをテーブル全体に対して結合して、関連するプロパティ値を取得します。基本的に、サブクエリはグループごとにmax(id)を持たないすべての行を破棄します。

SELECT kvtable.* 
FROM
  kvtable
  JOIN (
    SELECT
      MAX(id) AS id,
      user_id,
      property
    FROM kvtable
    /* optionally limit by user_id */
    WHERE user_id = <someuser>
    GROUP BY user_id, property
  ) maxids ON kvtable.id = maxids.id
于 2012-05-29T14:11:05.770 に答える