Mysql
 sql >> Datenbank >  >> RDS >> Mysql

2-Tabellen-Interaktion:einfügen, Ergebnis abrufen, einfügen

Ad 1 und 2:Ihr Datenmodell ist in Ordnung. Die Verwendung von Fremdschlüsseln ist hier entscheidend. Eine weitere Sache, um die Sie sich kümmern müssen, ist, dass die Datenbank sicherstellen sollte, dass es einen TOPIC-Datensatz für jeden POST gibt. Dies wird durch Setzen von POST.topic_id NOT NULL erreicht Attribut. Dies ist ein ausreichender Sicherheitsmechanismus auf der DB-Seite, da er sicherstellt, dass kein POST ohne TOPIC bleibt. Egal, was Sie jetzt mit Ihrem POST machen, Sie sind verpflichtet, ein TOPIC anzugeben.

Zu 3:Ein Trigger mit gespeicherter Prozedur wird hier nicht empfohlen, da Sie zusätzliche Daten in Ihrer TOPIC-Tabelle haben (IsSticky, IsLocked usw.), die Sie möglicherweise bei der Erstellung des TOPIC-Datensatzes bereitstellen möchten. Wenn ein solcher Auslöser anwendbar wäre, würde das Datenbankdesign außerdem Gegenstand einer Denormalisierung sein.

Ad 4:Auf der Seite der Geschäftslogik können Sie sich jetzt selbst helfen, indem Sie einen automatisierten Mechanismus schreiben, um den TOPIC-Datensatz jedes Mal zu erstellen, wenn ein neuer POST-Datensatz ohne angegebene topic_id erstellt wird. Ich empfehle, dafür etwas ORM zu verwenden oder die in jedem MVC-Framework verfügbaren Datenmodelle zu nutzen. Die Blaupause für solche Modelle würde wie folgt aussehen:

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

    // ...
}

Hinweis:Als gute MVC-Praxis sollten diese Modelle der einzige Ort sein, an dem direkt auf den Tabellenzeilen gearbeitet werden kann. Andernfalls erhalten Sie am Ende SQL-Fehler (das Datenmodell bleibt jedoch kohärent, sodass Sie sich keine Sorgen machen müssen, dass etwas kaputt geht).

Profitieren Sie endlich von Ihren Modellen im Controller Schicht:

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