首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >2-表交互:插入,获取结果,插入

2-表交互:插入,获取结果,插入
EN

Stack Overflow用户
提问于 2012-12-16 20:53:56
回答 3查看 236关注 0票数 2

我需要做一个基本的决定,我的数据库/网络互动,我错过了知识,甚至找到适当的搜索条件。

背景:

我正在建立一个家庭网站,支持一个论坛,家谱,pvp游戏与排名和更多的细节,所有从一个数据模型。现在的技术: Php,MySQL,javascript,面向对象的方式。

要求:

在论坛数据模型中,处理一个书面文章作为一个新的论坛主题(线程)。

现行办法:

在我当前的数据模型中,这将意味着在两个表上进行更新: Post和Topic。我需要在表中插入一行,然后获取新生成的topicId(序列),然后在post表的插入中使用该行。

问题:

-我觉得这是太多的工作,需要发生的事情,太多的互动。但是,如果我坚持目前的方法,这将成为一个典型的要求。

问题:

  1. 我是在正确的轨道上,还是我应该
  2. 重组数据模型或
  3. 选择另一种数据库交互方式(例如存储过程)
  4. 我是否面临一个典型的例子,您将使用方法学/框架xyz。

目前,表具有如下结构(松散地基于来自这一个的erdiagrams.com)

主题:(“线程”)

代码语言:javascript
复制
id
Forum_ID (FK)
Person_ID (FK)(threadcreator)
IsLocked
IsSticky
Subject
ViewCount
DateCreated
Tc_post_id  - trigger to last post_id in this thread

POST

代码语言:javascript
复制
id
topic_id(FK)
person_id(FK)
subject
message
timestamp
replyto

然后,我有一个视图,收集每个主题的最后一篇文章,并在触发器Tc_post_id上显示一些信息(例如,最后一张海报图片)。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-12-18 04:13:04

广告1和2:你的数据模型很好。在这里使用外键是很关键的。您还需要注意的另一件事是,数据库应该确保每个帖子都有一个主题记录。这是通过设置POST.topic_id NULL属性来完成的。在DB端,这是足够的安全机制,因为它确保不会有任何帖子没有主题。无论你现在如何处理你的帖子,你都有义务提供一个主题。

广告3:此处不建议使用带有存储过程的触发器,因为主题表(IsSticky、IsLocked等)中有其他数据,您可能希望在创建主题记录时提供这些数据。此外,如果这种触发器适用,数据库设计将受到非正规化的影响。

广告4:在业务逻辑方面,您现在可以通过编写一种自动机制来帮助自己,每次创建新的POST记录时都不需要指定的topic_id,就可以创建主题记录。我建议为此使用一些ORM,或者利用任何MVC框架中可用的数据模型。这类模型的蓝图如下:

代码语言:javascript
复制
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错误(但数据模型将保持一致性,因此您不必担心某些东西会崩溃)。

最后,利用控制器层中的模型:

代码语言:javascript
复制
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
EN

Stack Overflow用户

发布于 2012-12-16 20:58:14

我的理解是:主题是帖子的容器。

主题表将非常小,并且可能只包含topic id (PK)topic title

这些帖子本身将包含post id (PK)topic id (FK)timestampsauthor idtext

我会使用InnoDB和外键,这样一个被删除的主题就可以删除它的所有子帖子。

票数 0
EN

Stack Overflow用户

发布于 2012-12-16 22:53:22

(编辑:)在这个答案中,我发布了一种使用mysql_insert_id(),的方法,这仍然是一个技术上正确的解决方案(如果错误的话,请纠正我)。

但是,现在我将选择PDO包装器,我猜。而且,这也不是一般建模/方法问题的答案。

不过,以下是这样做的一种方法:

代码语言:javascript
复制
$sql = "INSERT INTO topic VALUES (NULL,'$forumId',<more parameters>)";
$result = mysql_query($sql);

#  get the generated id  
$topicId = mysql_insert_id();

#  and insert into the post table
$sql = "INSERT INTO post VALUES (NULL,'$topicId',<more parameters>)";
$result = mysql_query($sql);
mysql_free_result($result);

来源:http://www.desilva.biz/mysql/insertid.html

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13905381

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档