私は Rails アプリケーションを手伝っています。その目的は、そのアプリケーションをマルチテナントにすることです。これが意味することは、データベース テーブルに複数のユーザー/組織からのデータが存在し、多くの場合、アクセス パスは「組織のすべてのデータを取得する」という行に沿ったものになるということです。
データベースとして MYSQL を使用しています。
デフォルトでは、Rails は id 列を使用してテーブルに主キーを作成します。id 列は自動インクリメントされます。これはいくつかの点で便利です。行は常にテーブルの最後に追加されます。ただし、次の状況を考慮してください。
- foo というオブジェクト。fooにはIDがあり、常にorganisation_idがあります
- 各組織がデータベースに foo を作成すると、これらの foo はテーブル全体にインターリーブされます (ID シーケンスで格納されます)。
- この組織のすべての foo を一覧表示するユース ケース
私が抱えている問題は、組織の foo がデータベース内で密接に配置されていないことです。実際、それらは非常に最適に分散されていません。理想的には、テーブルに (organisation_id, id) の主キーを作成します。これにより、特定の組織のすべての foo がテーブルに並んで表示されます。
残念ながら、これを行うと、Rails から「モデル Foo のテーブル foo の主キーが不明です」というエラーが表示されます。複合キーgemをレールに使用することでこれに対処できると思いますが、データベースレベルでこれを透過的にする方法が必要なようです。
別のアプローチはありますか?
参考までに、データベースでインデックスを変更するコマンドは次のとおりです。
ALTER TABLE foos ADD KEY (id); # id カラムは自動インクリメントなので必要
ALTER TABLE foos DROP PRIMARY KEY, ADD PRIMARY KEY(organisation_id, id);
EDIT 1:composite_primary_keys gemを使用して正確にこれを行うことに成功したことを示すブログ投稿。これにより、そのアプローチに少し自信が持てるようになりました。問題は、2008 年からのものであるため、物事が進んでいる可能性があることです。 http://www.joehruska.com/?p=6
編集 2: 私が検討していた別のオプションは、代わりにパーティショニングを行うことでした。組織の数はおそらく最大パーティションを超えないでしょうし、メリットをあまり失うことなくそれらを少しグループ化することもできます。残念ながら、重要な引用は、テーブルのすべての一意のキーがテーブルのパーティション式のすべての列を使用する必要があるということです。(これにはテーブルの主キーも含まれます- MYSQL マニュアルhttp://dev.mysql.com/doc/refman/5.6/en/partitioning-limitations-partitioning-keys-unique-keys.htmlから) 。
そのため、複合主キーが再び必要になります。Rails が単にキーが存在することよりも、主キーを重視していることに少し驚いています。