28. Best Practices

The best practices mentioned here that affect database design generally refer to best practices when working with Doctrine and do not necessarily reflect best practices for database design in general.

ここで言及されているデータベース設計に影響を与えるベスト プラクティスは、通常、Doctrine を使用する場合のベスト プラクティスを参照しており、一般的なデータベース設計のベスト プラクティスを必ずしも反映しているわけではありません。

28.1. Constrain relationships as much as possible

It is important to constrain relationships as much as possible. This means:


  • Impose a traversal direction (avoid bidirectional associations if possible)

    トラバーサル方向を強制する (可能であれば双方向の関連付けを避ける)

  • Eliminate nonessential associations


This has several benefits:


  • Reduced coupling in your domain model

    ドメイン モデルでの結合の削減

  • Simpler code in your domain model (no need to maintain bidirectionality properly)

    ドメイン モデルのコードを簡素化 (双方向性を適切に維持する必要はありません)

  • Less work for Doctrine

    Doctrine の作業が減る

28.2. Avoid composite keys

Even though Doctrine fully supports composite keys it is best not to use them if possible. Composite keys require additional work by Doctrine and thus have a higher probability of errors.

Doctrine は複合キーを完全にサポートしていますが、可能な限り複合キーを使用しないことをお勧めします。複合キーはDoctrineによる追加作業を必要とするため、エラーの可能性が高くなります。

28.3. Use events judiciously

The event system of Doctrine is great and fast. Even though making heavy use of events, especially lifecycle events, can have a negative impact on the performance of your application. Thus you should use events judiciously.

Doctrine のイベント システムは素晴らしく、高速です。イベント、特にライフサイクル イベントを多用すると、アプリケーションのパフォーマンスに悪影響を及ぼす可能性があります。したがって、イベントは慎重に使用する必要があります。

28.4. Use cascades judiciously

Automatic cascades of the persist/remove/merge/etc. operations are very handy but should be used wisely. Do NOT simply add all cascades to all associations. Think about which cascades actually do make sense for you for a particular association, given the scenarios it is most likely used in.

永続化/削除/マージ/その他の自動カスケード。操作は非常に便利ですが、賢明に使用する必要があります。 allcascades をすべての関連付けに単純に追加しないでください。使用される可能性が最も高いシナリオを考慮して、特定の関連付けに対してどのカスケードが実際に意味があるかを考えてください。

28.5. Don’t use special characters

Avoid using any non-ASCII characters in class, field, table or column names. Doctrine itself is not unicode-safe in many places and will not be until PHP itself is fully unicode-aware.

クラス、フィールド、テーブル、または列の名前に非 ASCII 文字を使用しないでください。 Doctrine 自体は多くの場所で Unicode に対して安全ではなく、PHP 自体が完全に Unicode 対応になるまで安全ではありません。

28.6. Don’t use identifier quoting

Identifier quoting is a workaround for using reserved words that often causes problems in edge cases. Do not use identifier quoting and avoid using reserved words as table or column names.

識別子の引用は、予約語を使用するための回避策であり、エッジ ケースで問題を引き起こすことがよくあります。識別子の引用符を使用しないでください。テーブルまたは列の名前として予約語を使用しないでください。

28.7. Initialize collections in the constructor

It is recommended best practice to initialize any business collections in entities in the constructor. Example:


namespace MyProject\Model;
use Doctrine\Common\Collections\ArrayCollection;

class User {
    /** @var Collection<int, Address> */
    private Collection $addresses;
    /** @var Collection<int, Article> */
    private Collection $articles;

    public function __construct() {
        $this->addresses = new ArrayCollection;
        $this->articles = new ArrayCollection;

28.8. Don’t map foreign keys to fields in an entity

Foreign keys have no meaning whatsoever in an object model. Foreign keys are how a relational database establishes relationships. Your object model establishes relationships through object references. Thus mapping foreign keys to object fields heavily leaks details of the relational model into the object model, something you really should not do.

外部キーは、オブジェクト モデルではまったく意味がありません。外部キーは、リレーショナル データベースが関係を確立する方法です。オブジェクト モデルは、オブジェクト参照を通じて関係を確立します。したがって、オブジェクト フィールドへの外部キーのマッピングは、リレーショナル モデルの詳細をオブジェクト モデルに大量に漏らすことになります。

28.9. Use explicit transaction demarcation

While Doctrine will automatically wrap all DML operations in a transaction on flush(), it is considered best practice to explicitly set the transaction boundaries yourself. Otherwise every single query is wrapped in a small transaction (Yes, SELECT queries, too) since you can not talk to your database outside of a transaction. While such short transactions for read-only (SELECT) queries generally don’t have any noticeable performance impact, it is still preferable to use fewer, well-defined transactions that are established through explicit transaction boundaries.

Doctrine は flush() のトランザクションですべての DML 操作を自動的にラップしますが、トランザクション境界を自分で明示的に設定することをお勧めします。そうしないと、トランザクションの外部でデータベースと通信できないため、すべてのクエリが小さなトランザクション (そう、SELECT クエリも) にラップされます。読み取り専用 (SELECT) クエリのこのような短いトランザクションは、通常、顕著なパフォーマンスへの影響はありませんが、明示的なトランザクション境界を介して確立された、明確に定義された少数のトランザクションを使用することをお勧めします。

Table Of Contents

Previous topic

27. Metadata Drivers

27. メタデータドライバー

Next topic

29. Limitations and Known Issues

29. 制限事項と既知の問題

This Page

Fork me on GitHub