2016-11-29 3 views
0

私はデータベースの内部にテーブルを3つ持っています:interestsubscriptionsubscriberです。スキーマは次のようになります。共通のテーブルを使って関係を正しく確立する

Subscribr Database schema

サブスクリプションテーブルには関心とサブスクライバの両方で一対多の関係を持っています。どのように動作させたいのですが、どのように動作させたいのか、そして実際にどのように動作しているのかは分かりませんが、これは次のようなものです:加入者は複数のインタレストを持つことができ、複数の加入者。これにより、加入者がどのような関心を持っており、どの関心が加入しているのかを見ることができます。次に、サブスクリプションは、1つのサブスクライバと1つの関心事にのみ関係します。

C:\xampp\htdocs\www\public_html\playground\subscribr>php list_subscriptions.php 
[email protected] 
--Magazine 
--Newsletter 
--Promotions 
--Email 
[email protected] 
--Magazine 
--Promotions 
[email protected] 
--Newsletter 
--Email 
-te[email protected] 
--Magazine 
--Promotions 
--Email 
[email protected] 
--Magazine 
[email protected] 
--Newsletter 
[email protected] 
--Promotions 
[email protected] 
--Promotions 
[email protected] 
--Newsletter 

I:私はもっとこのような結果を期待するとし

C:\xampp\htdocs\www\public_html\playground\subscribr>php list_subscriptions.php 
[email protected] 
--Magazine 
[email protected] 
--Newsletter 
[email protected] 
--Promotions 
[email protected] 
--Email 
[email protected] 
--Magazine 
[email protected] 
--Promotions 
[email protected] 
--Newsletter 
[email protected] 
--Email 
[email protected] 
--Magazine 
[email protected] 
--Promotions 
[email protected] 
--Email 
[email protected] 
--Magazine 
[email protected] 
--Newsletter 
[email protected] 
--Promotions 
[email protected] 
--Promotions 
[email protected] 
--Newsletter 

私はそれはそれはセットアップが、私はちょうどサブスクリプションテーブルを照会いくつかのテストでしたし、私はこのバックを持っているかだと思いますサブスクライバによってクエリを実行し、サブスクリプションテーブルを使用して関心を取得すると、この結果が得られます。私はORMを使用していますので、それを行うためのコードは次のようになります。

$subscriberRepo = $entityManager->getRepository('Subscribr\Entity\Subscriber'); 
$subscribers = $subscriberRepo->findAll(); 

foreach ($subscribers as $subscriber) { 
    echo sprintf("-%s\n", $subscriber->getEmail()); 
    foreach ($subscriber->getInterests() as $interest) { 
     echo sprintf("--%s\n", $interest->getInterest()->getName()); 
    } 
} 

だから私は、このスキーマを使用して、に加入している加入者のサブスクリプション、および利益を得ることができますが、その後、ポイントが調和してありますサブスクリプションテーブルの周り?それとも、私がやりたいことをするために、すべてのことを再加工する必要がありますか?サブスクライバテーブルからis_subscribedを削除し、subscription_statusというサブスクリプションにカラムを追加するなど、サブスクリプションテーブルに余分なカラムを追加したい場合は、このソリューションが最もクリーンであると感じています。ただし、余分なフィールドを持つ結合テーブルのように感じることもほとんどありません。思考?

+0

サブスクリプションテーブル*は、余分なフィールドを持つ結合テーブルです。だから何?これは、あなたが多くを表現する方法です:属性を持つ多くのバイナリ関係。さらに、あなたが「どのようにして加入者の購読と購読している興味を得ることができるか」*です。 ORMはそれを使用してgetInterests()を実装します。 – philipxy

答えて

1

説明に基づいて、マップする必要があるものを適切に理解することができます。 Subscriber N - > N Interest
: - - > N Subscription
Subscription nは

それは間接的に意味

オプション1

Subscriber 1:簡単な方法では、2つのオプションがあり 見ない?上記のコードは、あなたのマッピングでは、以下の変更で動作します

foreach ($subscribers as $subscriber) { 
    echo sprintf("-%s\n", $subscriber->getEmail()); 
    foreach ($subscriber->getSubscriptions() as $subscription) { 
     echo sprintf("--%s\n", $subscription->getInterest()->getName()); 
    } 
} 

EDIT

:より良いを確認するためのコードをすることができます。このコードの説明:各サブスクライバがサブスクリプションのリストを持ち、各サブスクリプションが関心を持つようにリピートするサブスクライバを繰り返します。

Subscriber.php

/** 
    * @var array 
    * 
    * @ORM\OneToMany(targetEntity="Subscription", mappedBy="subscriber", cascade={"persist", "remove"}, orphanRemoval=TRUE) 
    */ 
    private $subscriptions; 

あなたはSubscriberからprivate $interests;を削除する必要があります。それはInterestに直接アクセスしません。

Subscription.php

/** 
* @var Interest 
* 
* @ORM\ManyToOne(targetEntity="Interest", inversedBy="subscribers") 
* @ORM\JoinColumn(name="interest_id", referencedColumnName="id", nullable=FALSE) 
*/ 
private $interest; 

お知らせ各Subscriptionは単一Interestにアクセスします。

この場合、この最初のオプションが最適です。

オプション2

あなたはSubscriptionクラスを削除し、参照テーブルとしてそのテーブルを使用することができます。そして直接地図:Subscriber n - > n Interest

class Subscriber { 

    /** 
     * @var array 
     * 
     * @ORM\ManyToMany(targetEntity="Interest", cascade={"persist", "remove"}, orphanRemoval=TRUE) 
     * @ORM\JoinTable(name="subscription", 
     *  joinColumns={@ORM\JoinColumn(name="subscriber_id", referencedColumnName="id")}, 
     *  inverseJoinColumns={@ORM\JoinColumn(name="interest_id", referencedColumnName="id")} 
     *  ) 
     */ 
     private $interests; 
} 

あなたはsubscription.interest_date「原因subscriptionテーブルを使用することはできません。このオプションでは問題は今だけ関係表です。その詳細については、this questionを参照してください。

+1

私が投稿したスキーマによると、すでにオプション1があるようです。それとも、私が紛失しているものがありますか。これは完全に可能です。 – mrClean

+1

はい。しかし、「購読者」は「購読」にアクセスし、「購読」には「興味」が1つずつあることに注意してください。そのため、オプション1のコードはあなたのコードとは少し異なります。オプション1にマッピングコードを含めるように編集します。 –

関連する問題