sql >> データベース >  >> RDS >> Mysql

2テーブルの相互作用:挿入、結果の取得、挿入

    広告1と2:データモデルは問題ありません。ここでは、外部キーを使用することが重要です。もう1つ注意する必要があるのは、データベースが各POSTにTOPICレコードがあることを確認する必要があるということです。これは、POST.topic_id NOT NULLを設定することによって行われます。 属性。これは、TOPICなしでPOSTが残されないことを保証するため、DB側で十分な安全メカニズムです。 POSTで現在何をしていても、トピックを提供する義務があります。

    広告3:トピックテーブルの作成時に提供する可能性のある追加データ(IsSticky、IsLockedなど)があるため、ここではストアドプロシージャを使用したトリガーはお勧めしません。また、そのようなトリガーが適用できる場合、データベース設計は非正規化の対象になります。

    広告4:ビジネスロジックの側面では、topic_idを指定せずに新しいPOSTレコードが作成されるたびに、TOPICレコードを作成する自動メカニズムを作成することで、自分自身を支援できるようになりました。これにはORMを使用するか、MVCフレームワークで利用可能なデータモデルを利用することをお勧めします。このようなモデルの青写真は次のようになります。

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

    注:MVCの優れた実践として、これらのモデルはテーブルの行を直接操作する唯一の場所である必要があります。そうしないと、SQLエラーが発生することになります(ただし、データモデルは一貫性を保つため、何かが壊れることを心配する必要はありません)。

    最後に、コントローラーでモデルを活用します レイヤー:

    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. EXPLAINプランに基づいてMySQLクエリを最適化する方法

    2. カンマ区切りの文字列を使用したMySQL検索

    3. Oracleの簡単な変換/移行へのMSAccess

    4. PostgreSQL 11のデプロイと管理:ClusterControl1.7.1の新機能