title: Project rework : Should I use primary composite keys and json for translations with Laravel?
body: <h1>Context</h1>
  
  <p>I am completely reworking a website (code and database) using Laravel 7 and Mysql.<br>
  The goal is to rebuild the entire project by making the best use of best practices.<br>
  In this project, I have many database tables and relations between them, and I'm also working with a lot of user-defined contents.</p>
  
  <h1>Problem 1</h1>
  
  <p>In relational database design, it's a good practice to use <code>composite primary keys</code> when you know for a fact that an <code>id</code> is useless (pivot tables for example).<br>
  But I know that Laravel does not handle <code>composite primary keys</code> for models and relationships, you have to install some external packages or do it yourself with Trait/Class inheritance.  </p>
  
  <p>So, I wonder if I should use <code>composite primary keys</code>, or if I should stick with a default auto-increment <code>id</code> along with a <code>composite unique key</code>?</p>
  
  <p>To show an example of what I mean, I have to choose between idea 1 or idea 2, or maybe something else ?</p>
  
  <h2>Idea 1 : With standard primary key</h2>
  
  <pre><code>Schema::create('user_documents', function (Blueprint $table) {
      $table-&gt;id();
      $table-&gt;foreignId('user_id')-&gt;constrained();
      $table-&gt;foreignId('document_id')-&gt;constrained();
      $table-&gt;string('file_name', 50);
      $table-&gt;json('comments')-&gt;nullable();
      // [...] Maybe some more columns
      $table-&gt;timestamps();
  
      $table-&gt;unique(['user_id', 'document_id']);
  });
  </code></pre>
  
  <h2>Idea 2 : With composite primary key</h2>
  
  <pre><code>Schema::create('user_documents', function (Blueprint $table) {
      $table-&gt;foreignId('user_id')-&gt;constrained();
      $table-&gt;foreignId('document_id')-&gt;constrained();
      $table-&gt;string('file_name', 50);
      $table-&gt;json('comments')-&gt;nullable();
      // [...] Maybe some more columns
      $table-&gt;timestamps();
  
      $table-&gt;primary(['user_id', 'document_id']);
  });
  </code></pre>
  
  <h1>Problem 2</h1>
  
  <p>You may have noticed I used a <code>json</code> type for the <code>comments</code> column.<br>
  That's because the user could write a comment in one or many languages when he uploads a file.</p>
  
  <p>Values for this column looks like this :</p>
  
  <pre><code>{
      "en": "a comment in english",
      "fr": "a comment in french",
      "*": "the comment for all other languages"
  }
  </code></pre>
  
  <p>If he wants everyone to see the same text whatever the language, we could have this :</p>
  
  <pre><code>{
      "*": "the comment for all languages"
  }
  </code></pre>
  
  <p>I have a lot of things working like this for user-defined multilingual content, and I thought this approach would be better than having specific tables for translations.  </p>
  
  <p>But I'm not sure that's a good practice to use that much <code>json</code> columns, is there a better thing to do for translations ?</p>