sql >> Databasteknik >  >> RDS >> Mysql

Interaktion med 2 tabeller:infoga, få resultat, infoga

Annons 1 och 2:Din datamodell är bra. Att använda främmande nycklar är avgörande här. En sak till som du måste ta hand om är att databasen ska säkerställa att det finns en TOPIC-post för varje POST. Detta görs genom att ställa in POST.topic_id NOT NULL attribut. Detta är tillräcklig säkerhetsmekanism på DB-sidan, eftersom det säkerställer att ingen POST lämnas utan TOPIC. Oavsett vad du gör nu med din POST är du skyldig att tillhandahålla ett TOPIC.

Annons 3:En trigger med lagrad procedur rekommenderas inte här eftersom du har ytterligare data i din TOPIC-tabell (IsSticky, IsLocked, etc), som du kanske vill tillhandahålla när TOPIC-posten skapas. Dessutom, om en sådan trigger skulle vara tillämplig, skulle databasdesignen vara föremål för denormalisering.

Annons 4:På affärslogiksidan kan du nu hjälpa dig själv genom att skriva en automatiserad mekanism för att skapa TOPIC-posten varje gång en ny POST-post skapas utan specificerat topic_id. Jag rekommenderar att du använder lite ORM för detta eller drar fördel av datamodellerna som finns tillgängliga i alla MVC-ramverk. Ritningen för sådana modeller skulle se ut så här:

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

    // ...
}

Notera:som en god MVC-praxis bör dessa modeller vara det enda stället att direkt arbeta på tabellraderna. Annars kommer du att få SQL-fel (men datamodellen kommer att förbli sammanhängande, så du behöver inte oroa dig för att något ska gå sönder).

Äntligen dra nytta av dina modeller i kontrollen lager:

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. Vad är SQL-operatörer och hur fungerar de?

  2. Är det lagligt att använda MySQL i kommersiell miljö?

  3. Hur kan jag hämta en lista med parametrar från en lagrad procedur i SQL Server

  4. Hur sammanfogar man många rader med samma id i sql?