sql >> Database teknologi >  >> RDS >> Mysql

2-bords interaktion:indsæt, få resultat, indsæt

Ad 1 og 2:Din datamodel er fin. Brug af fremmednøgler er afgørende her. En ting mere, du skal passe på, er, at databasen skal sikre, at der er en TOPIC-post for hver POST. Dette gøres ved at indstille POST.topic_id NOT NULL attribut. Dette er tilstrækkelig sikkerhedsmekanisme på DB-siden, da det sikrer, at ingen POST efterlades uden TOPIC. Lige meget hvad du gør nu med din POST, er du forpligtet til at give et TOPIC.

Ad 3:En trigger med lagret procedure anbefales ikke her, da du har yderligere data i din TOPIC-tabel (IsSticky, IsLocked, osv.), som du måske ønsker at angive ved oprettelse af TOPIC-post. Hvis en sådan trigger også ville være anvendelig, ville databasedesignet være genstand for denormalisering.

Ad 4:På forretningslogiksiden kan du nu hjælpe dig selv ved at skrive en automatiseret mekanisme til at oprette TOPIC-posten, hver gang en ny POST-post oprettes uden specificeret topic_id. Jeg anbefaler at bruge noget ORM til dette eller drage fordel af de tilgængelige datamodeller i enhver MVC-ramme. Planen for sådanne modeller ville se sådan ud:

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;
    }

    // ...
}

Bemærk:Som en god MVC-praksis bør disse modeller være det eneste sted, hvor man kan operere direkte på tabelrækkerne. Ellers ender du med at få SQL-fejl (men datamodellen forbliver sammenhængende, så du behøver ikke bekymre dig om, at noget går i stykker).

Udnyt endelig dine modeller i controlleren lag:

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. MySQL - Hvordan SUMMER man tider?

  2. Brug af union og orden efter klausul i mysql

  3. Hvorfor virker mit database backup-script ikke i php?

  4. SQL-forespørgsel for at returnere maksimumsværdier over årtier