Databáze
Pojmenování sloupců
- Primární klíč by měl vždy být
id
- Cizí klíče by měly být zapsány v jednotném čísle a s příponou
_id
(user_id
,product_id
,category_id
...) - Když volíte jméno, buďte opatrní s rezervovanými slovy
Doporučené názvy pro často používané sloupce:
Tato pojmenování jsou doporučením jak pojmenovat určité sloupce a tím je sjednotit napříč projekty. Tyto sloupce se mohou nazývat i jinak, ale je dobré držet je sjednocené.
- order_column - název pro řazení entit (např. drag & drop)
- company_number - název pro IČO / Identifikační Číslo Organizace
- vat_number - název pro DIČ / Daňové Identifikační Číslo
- zip_code - název pro PSČ
Názvy podle datového typu sloupce:
Doporučené prefixy/sufixy pro pojmenování sloupců.
-
boolean -
is_enabled
,has_reviews
-
timestamp -
published_at
,valid_from
,scheduled_for
Pro tip: Některé boolean sloupce by mohly být převedeny na timestamp (např. z
is_finished
nafinished_at
). Výhodou je, že máte ve skutečnosti dvě informace v jednom sloupci.
Řazení sloupců
Toto řazení pomáhá k lepšímu čtení a orientaci v databázi.
- id - vždy by mělo být první
- cizí klíče
- ostatní sloupce - měly by být seřazené podle priorit a seskupiné podle kontextu
-
nativní timestampy -
created_at
,updated_at
UUIDs
Bezpečná alternativa k ID. Měla by být používána pro veřejně přístupné webové stránky nebo pro některé tabulky s citlivým obsahem (bankovní účty, objednávky, faktury...). Jak používat UUIDs?
Indexy
Indexy jsou struktury databáze, které umožňují rychlejší získávání dat. Fungují tak, že vytvářejí samostatnou datovou strukturu, která ukazuje na umístění dat v databázi. Při spuštění dotazu může databáze použít index k rychlému nalezení relevantních dat místo prohledávání celé databáze.
Pro tip: Použijte indexy na sloupce, které jsou často dotazovány nebo používány v joinech a výkon vaší databáze se zlepší.
Migrace
Migrace jsou způsob verzování schématu vaší databáze. Umožňují vám provádět změny v schématu Vaší databáze přehledným způsobem a umožňují Vám také snadný způsob jak vrátit změny zpět, když je to nutné. Více informací
Best practices
- Během vývoje je v pořádku upravovat existující migrace a spouštět příkaz
php artisan migrate:fresh
pro resetování databáze. - Jakmile je projekt v produkčním prostředí, musíte vytvořit novou migraci pro každou změnu, i malou.
- Nerozbijte řazení sloupců - při přidávání nového sloupce použijte metody k řazení
after()
nebobefore()
. - Přidejte krátkou poznámku pomocí metody
comment()
, pokud název sloupce není výstižný (např. odborné výrazy).
Pro tip: Při vývoji se postupem času může hromadit stále více a více migrací. To může vést k nadměrnému počtu souborů v adresáři
database/migrations
, kde mohou být stovky migrací. Pokud chcete, můžete své migrace "squashnout" do jednoho SQL souboru. Více informací
Seedery
Seedery slouží k naplnění databáze počátečními/testovacími daty. Jsou zvláště užitečné v situacích, kdy potřebujete naplnit databázi předem existujícími daty, jako jsou testovací nebo referenční data.
Použitím seedru můžete rychle naplnit databázi potřebnými daty, aniž byste je museli pokaždé zadávat ručně. Více informací
-
Příkaz pro vytvoření:
php artisan make:seeder UserSeeder
-
Spuštění všech seederů:
php artisan db:seed
-
Spuštění konkrétního seederu:
php artisan db:seed --class=UserSeeder
Pro tip: Někdy je třeba v seederech vypnout eventy modelu. To lze jednoduše provést pomocí trait
WithoutModelEvents
. Více informací
Pojmenování
Jednotné číslo s příponou "Seeder" (UserSeeder
, ProductSeeder
, CategorySeeder
...)
Factories
Factories v Laravelu jsou pohodlný způsob jak generovat falešná data pro účely testování. Umožňují vám rychle a snadno vytvářet instance vašich modelů s náhodnými nebo vlastními atributy.
Definováním factory pro každý z vašich modelů můžete snadno generovat data, která potřebujete pro testování funkcionality vaší aplikace.
Jsou převážně používány v seederech a testech. Více informací
Příkaz pro vytvoření: php artisan make:factory UserFactory
1class ProductFactory extends Factory 2{ 3 public function definition(): array 4 { 5 return [ 6 'name' => fake()->name(), 7 'category_id' => Category::factory(), 8 ... 9 ];10 }11}
Pojmenování
Název modelu s příponou "Factory" (UserFactory
, ProductFactory
, CategoryFactory
...)
Ukázky použití
Vytvoření jednoho záznamu v databázi:
1User::factory()->create();
Vytvoření jedné instance modelu:
1User::factory()->make();
Vytvoření více záznamů v databázi:
1User::factory()2 ->count(10)3 ->create();
Vytvoření více instancí modelu:
1User::factory()2 ->count(10)3 ->make();
Vytvoření factory s vlastní hodnotou:
1User::factory()->create(['email' => 'info@rockero.cz']);
Factory metody
Sequence
Můžete vytvářet modely s větší variabilitou dat. Sekvence je opakována, dokud není dosaženo požadovaného počtu modelů. Více informací
1// Creates 5 orders with state new and 5 orders with state pending:2Order::factory()3 ->count(10)4 ->sequence(5 ['state' => 'new'],6 ['state' => 'pending']7 )8 ->create();
Můžete používat sequence také s callbackem:
1Category::factory()2 ->count(10)3 ->sequence(fn (Sequence $sequence) => ['order_column' => $sequence->index])4 ->create();
Recycle
Někdy se stane, že vnořené factories mají stejný vztah jako základní factory. V takovém případě můžete použít metodu recycle()
. Tato metoda opětovně použije instanci vztahu. Více informací
1$tenant = Tenant::factory()->create(); 2 3// Bad example: 4Product::factory()->create(['tenant_id' => $tenant]); 5ProductCategory::factory()->create(['tenant_id' => $tenant]); 6 7// Good example: 8Product::factory() 9 ->recycle($tenant)10 ->has(ProductCategory::factory())11 ->create();
Vztahy
1// Creates user with 3 posts: 2User::factory() 3 ->has(Post::factory()->count(3)) 4 ->create(); 5 6// Or using magic methods: 7User::factory() 8 ->hasPosts(3) 9 ->create();10 11// Creates post that belongs to the user:12Post::factory()13 ->count(3)14 ->for(User::factory(['name' => 'Rockero']))15 ->create();16 17// Or using magic methods:18Post::factory()19 ->count(3)20 ->forUser(['name' => 'Rockero'])21 ->create();22 23// Creates user with 3 roles and custom pivot value:24User::factory()25 ->hasAttached(26 Role::factory()->count(3),27 ['active' => true]28 )29 ->create();30 31// Or using magic methods:32User::factory()33 ->hasRoles(1, ['name' => 'Editor'])34 ->create();
Vlastní metody
Místo vytváření klienta s následujícími hodnotami v každém testu:
1Client::factory([2 'platform' => 'github',3 'email' => 'info@rockero.cz'4])->create();
lze vytvořit vlastní metoda v ClientFactory
:
1public function github(array $attributes = []): self2{3 return $this->state([4 'platform' => 'github',5 'email' => $attributes['email'] ?? fake()->email()6 'access_token' => $attributes['token'] ?? Str::random()7 ]);8}
a pak ji můžete používat následovně:
1Client::factory()2 ->github()3 ->create();
Factory Callbacks
Factory callbacks můžou být použité k provedení akce po vytvoření nebo uložení modelu.
Tyto metody jsou definovány uvnitř metody configure()
v třídě factory.
1public function configure(): static2{3 return $this->afterMaking(function (User $user) {4 // ...5 })->afterCreating(function (User $user) {6 // ...7 });8}