sql >> Database >  >> RDS >> Mysql

Interactie met 2 tabellen:invoegen, resultaat krijgen, invoegen

Advertentie 1 en 2:Uw datamodel is in orde. Het gebruik van externe sleutels is hierbij cruciaal. Nog iets waar je voor moet zorgen, is dat de database ervoor moet zorgen dat er een TOPIC-record is voor elke POST. Dit wordt gedaan door POST.topic_id NIET NULL in te stellen attribuut. Dit is voldoende veiligheidsmechanisme aan de DB-kant, omdat het ervoor zorgt dat er geen POST wordt achtergelaten zonder TOPIC. Wat je nu ook doet met je POST, je bent verplicht een ONDERWERP op te geven.

Ad 3:Een trigger met opgeslagen procedure wordt hier niet aanbevolen, omdat u aanvullende gegevens in uw TOPIC-tabel heeft (IsSticky, IsLocked, enz.), die u mogelijk wilt opgeven bij het maken van een TOPIC-record. Als een dergelijke trigger van toepassing zou zijn, zou het ontwerp van de database ook onderhevig zijn aan denormalisatie.

Ad 4:Wat de bedrijfslogica betreft, kun je jezelf nu helpen door een geautomatiseerd mechanisme te schrijven om het TOPIC-record te creëren telkens wanneer een nieuw POST-record wordt gemaakt zonder gespecificeerde topic_id. Ik raad aan om hiervoor wat ORM te gebruiken of gebruik te maken van de datamodellen die beschikbaar zijn in elk MVC-framework. De blauwdruk voor dergelijke modellen ziet er als volgt uit:

abstract class AModel // this class should be provided by ORM or framework
{
    /**
     * @var PDO
     */
    protected $_db_driver;

    public function getLastInsertId()
    {
        $stmt = $this->_db_driver->prepare('SELECT LAST_INSERT_ID() AS id');
        $stmt->execute();
        return $stmt->fetch(PDO::FETCH_OBJ)->id;
    }

    public abstract function getFieldList();
}

class ForumTopicModel extends AModel
{
    public function insert(array $data)
    {
        $sql = 'INSERT INTO topic VALUES (:id, :forum_id, :person_id, :is_locked, ...)';
        $stmt = $this->_db_driver->prepare($sql);
        return $stmt->execute($data);
    }

    public function getFieldList()
    {
        return array('id', 'forum_id', 'person_id', 'is_locked', /*...*/);
    }

    // ...
}

class ForumPostModel extends AModel
{
    public function insert(array $data)
    {
        $sql = 'INSERT INTO post VALUES (:id, :topic_id, :person_id, :subject, ...)';
        $stmt = $this->_db_driver->prepare($sql);
        return $stmt->execute($data);
    }

    public function getFieldList()
    {
        return array('id', 'topic_id', 'person_id', 'subject', /*...*/);
    }

    public function insertInitialTopicPost(array $form_data)
    {
        $this->_db_driver->beginTransaction();

        $result = true;

        if ( empty($form_data['topic_id']) ) {
            // no topic_id provided, so create new one:
            $topic = new ForumTopicModel();
            $topic_data = array_intersect_key(
                $form_data, array_flip($topic->getFieldList())
            );
            $result = $topic->insert($topic_data);
            $form_data['topic_id'] = $topic->getLastInsertId();
        }

        if ( $result ) {
            $forum_post_data = array_intersect_key(
                $form_data, array_flip($this->getFieldList())
            );
            $result = $this->insert($forum_post_data);
        }

        if ( $result ) {
            $this->_db_driver->commit();
        }
        else {
            $this->_db_driver->rollBack();
        }

        return $result;
    }

    // ...
}

Opmerking:als een goede MVC-praktijk zouden die modellen de enige plaats moeten zijn om direct op de tafelrijen te werken. Anders krijg je uiteindelijk SQL-fouten (maar het datamodel blijft coherent, dus je hoeft je geen zorgen te maken dat er iets kapot gaat).

Profiteer ten slotte van uw modellen in de controller laag:

class ForumPostController extends AController
{
    public function createInitialTopicPostAction()
    {
        $form_data = $this->getRequest()->getPost(); /* wrapper for getting
            the $_POST array */

        // (...) validate and filter $form_data here

        $forumPost = new ForumPostModel();
        $result = $forumPost->insertInitialTopicPost($form_data);

        if ( $result ) {
            // display success message
        }
        else {
            // display failure message
        }
    }
}


  1. Hoe Ruby on Rails configureren met Oracle?

  2. MySQL-back-up en herstel vanaf de opdrachtregel

  3. T-SQL XOR-operator

  4. Wat is zout in relatie tot MYSQL sha1?