Mysql
 sql >> база данни >  >> RDS >> Mysql

Взаимодействие с 2 таблици:вмъкване, получаване на резултат, вмъкване

Реклама 1 и 2:Вашият модел на данни е наред. Използването на външни ключове тук е от решаващо значение. Още едно нещо, за което трябва да се погрижите е, че базата данни трябва да гарантира, че има запис TOPIC за всяка публикация. Това се прави чрез задаване на POST.topic_id NOT NULL атрибут. Това е достатъчен защитен механизъм от страна на DB, тъй като гарантира, че нито един POST няма да остане без ТЕМА. Без значение какво правите сега с вашия ПОСТ, вие сте длъжни да предоставите ТЕМА.

Реклама 3:Тук не се препоръчва задействане със съхранена процедура, тъй като имате допълнителни данни във вашата таблица TOPIC (IsSticky, IsLocked и т.н.), които може да искате да предоставите при създаването на запис TOPIC. Освен това, ако такъв тригер е приложим, дизайнът на базата данни ще подлежи на денормализация.

Реклама 4:От страна на бизнес логиката вече можете да си помогнете, като напишете автоматизиран механизъм за създаване на запис TOPIC всеки път, когато се създаде нов POST запис без посочен topic_id. Препоръчвам да използвате някакъв 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. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Разлика между базите данни в паметта и базата данни с дискова памет

  2. Хвани изключение за вмъкване на дублиран ключ

  3. Как да получите данни за последните 12 месеца в MySQL

  4. Как да съхранявате списък с дни от седмицата в MySQL?

  5. Съхраняване на артикули от пазарската количка в бисквитки и база данни