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