Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Interakcja 2-tabelowa:wstaw, uzyskaj wynik, wstaw

Ad 1 i 2:Twój model danych jest w porządku. Kluczowe jest tutaj używanie kluczy obcych. Jeszcze jedną rzeczą, o którą musisz zadbać, jest to, że baza danych powinna zapewniać, że dla każdego POST znajduje się rekord TOPIC. Odbywa się to poprzez ustawienie POST.topic_id NOT NULL atrybut. Jest to wystarczający mechanizm bezpieczeństwa po stronie DB, ponieważ zapewnia, że ​​żaden POST nie zostanie pozostawiony bez TOPIC. Bez względu na to, co teraz zrobisz ze swoim POST, jesteś zobowiązany do podania TEMATU.

Ad 3:Wyzwalacz z procedurą składowaną nie jest tutaj zalecany, ponieważ masz dodatkowe dane w tabeli TOPIC (IsSticky, IsLocked itp.), które możesz chcieć podać podczas tworzenia rekordu TOPIC. Ponadto, jeśli taki wyzwalacz miałby zastosowanie, projekt bazy danych podlegałby denormalizacji.

Ad 4:Po stronie logiki biznesowej możesz teraz pomóc sobie, pisząc zautomatyzowany mechanizm do tworzenia rekordu TOPIC za każdym razem, gdy tworzony jest nowy rekord POST bez określonego identyfikatora tematu. Polecam do tego użyć niektórych ORM lub skorzystać z modeli danych dostępnych w dowolnym frameworku MVC. Schemat dla takich modeli wyglądałby tak:

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

    // ...
}

Uwaga:zgodnie z dobrą praktyką MVC modele te powinny być jedynym miejscem, w którym można bezpośrednio operować na wierszach tabeli. W przeciwnym razie otrzymasz błędy SQL (ale model danych pozostanie spójny, więc nie musisz się martwić, że coś się zepsuje).

Na koniec skorzystaj ze swoich modeli w kontrolerze warstwa:

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. połącz java z mysql za pomocą jdbc na osx

  2. Postępowanie ze zduplikowanymi kluczami podstawowymi podczas wstawiania w SQLAlchemy (styl deklaratywny)

  3. Hibernacja hbm2ddl.auto domyślna wartość

  4. Zrzuć osadzoną bazę danych mysql do pliku tekstowego SQL

  5. Uporządkuj wyniki, aby dopasować kolejność wartości w wyrażeniu WHERE IN