title: How can I avoid a low-cardinality partition key in Cassandra?
body: <p>If I'm storing product data for multiple merchants in Cassandra, and I'd like to be able to retrieve an individual product or all products for a merchant, how can I avoid a low-cardinality partition key on that table? For example,</p>
  
  <pre class="lang-sql prettyprint-override"><code>CREATE TABLE products (
      merchant_id uuid,
      product_id text,
      description text,
  
      PRIMARY KEY (merchant_id, product_id)
  );
  </code></pre>
  
  <p>As far as I understand it, that works, but it has the problem that if I have a small number of merchants (dozens, say) and a large number of products (millions), the data won't be very well distributed across nodes.</p>
  
  <p>The workaround I've come up with is this:</p>
  
  <pre class="lang-sql prettyprint-override"><code>CREATE TABLE products (
      product_id text,
      merchant_id uuid,
      description text,
  
      PRIMARY KEY (product_id)
  );
  
  CREATE INDEX ON products (merchant_id);
  </code></pre>
  
  <p>In this case, the product ID has the merchant ID prepended to it to make it unique. This seems hacky. I'm also concerned that a lookup in the secondary index will return millions of primary keys.</p>
  
  <p>What is the correct thing to do here? I'm quite early in development, so I'm open to significant schema changes if necessary, and I'd like to do things the Right Way for Cassandra.</p>