Note that there are some explanatory texts on larger screens.

plurals
  1. POClustered indexes, mysql and Rails
    primarykey
    data
    text
    <p>I'm helping with a Rails application, the intent is for that application to be multi-tenanted. What this means is that there will be data from multiple users/organisations in the database tables, and often the access path will be along the lines of "get me all the data for my organisation".</p> <p>We're using MYSQL as the database.</p> <p>Rails by default creates a primary key on the table using the id column. The id column is auto-incremented. This is nice in some ways - rows are always added at the end of the table. However, consider the following situation:</p> <ul> <li>An object called foo. A foo has an id, and always has an organisation_id</li> <li>Over time each organisation creates foos in the database, these foos are interleaved throughout the table (they are stored in id sequence)</li> <li>A use case that involves listing all foos for this organisation</li> </ul> <p>The problem I have is that the foos for an organisation are not located closely together in the database, in fact they're spread around very sub-optimally. Ideally I'd create a primary key of (organisation_id, id) on the table, which would result in all foos for a given organisation being side by side in the table. </p> <p>Unfortunately, when I do this Rails gives me an 'Unknown primary key for table foos in model Foo' error. I think I could deal with this by using the composite keys gem to rails, but it seems like there should be some way to make this transparent at the database level.</p> <p>Is there an alternate approach?</p> <p>For reference, the command on the database to change my index was:</p> <p>ALTER TABLE foos ADD KEY (id); # needed because the id column is auto-increment</p> <p>ALTER TABLE foos DROP PRIMARY KEY, ADD PRIMARY KEY(organisation_id, id);</p> <p>EDIT 1: A blog post that indicates success doing exactly this with composite_primary_keys gem. Which gives me a bit more confidence with that approach, problem is that it's from 2008, so things may have moved on. <a href="http://www.joehruska.com/?p=6" rel="nofollow">http://www.joehruska.com/?p=6</a></p> <p>EDIT 2: Another option I was considering was partitioning instead - the number of organisations probably wouldn't exceed the maximum partitions, and I could probably group them a bit without losing too much benefit. Unfortunately, the key quote is <em>every unique key on the table must use every column in the table's partitioning expression. (This also includes the table's primary key</em> - from the MYSQL manual <a href="http://dev.mysql.com/doc/refman/5.6/en/partitioning-limitations-partitioning-keys-unique-keys.html" rel="nofollow">http://dev.mysql.com/doc/refman/5.6/en/partitioning-limitations-partitioning-keys-unique-keys.html</a>.</p> <p>So I'm still back needing a composite primary key again. I'm a little surprised that Rails cares so much about the primary key, rather than simply that a key is present. </p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload