我需要对我的数据库/网络交互做一个基本的决定,我甚至错过了找到合适搜索词的知识。
背景:
我正在建立一个家庭网站,它支持一个论坛,家庭树,pvp游戏与排名和更多的细节,所有从一个数据模型。目前的技术:面向对象的Php、MySQL、javascript。
要求:
在论坛数据模型中,将一篇书面文章作为新论坛主题(线程)的添加进行处理。
当前方法:
在我当前的数据模型中,这意味着需要更新两个表:Post和Topic。
我需要在topic表中插入一行,然后获取新生成的topicId(sequence),然后在post表的insert中使用它。
问题:
我觉得这是太多的工作需要发生什么,太多的互动。
但如果我坚持目前的做法,这将成为一个典型的要求。
问题:
我是不是走对了路
重新构造数据模型或
选择另一种数据库交互方式(例如存储过程)
我是否面临一个典型的例子,您将使用方法论/框架xyz。
当前的表有以下结构(松散地基于erdiagrams.com上的this one)
主题:(“线程”)
id
Forum_ID (FK)
Person_ID (FK)(threadcreator)
IsLocked
IsSticky
Subject
ViewCount
DateCreated
Tc_post_id - trigger to last post_id in this thread
岗位
id
topic_id(FK)
person_id(FK)
subject
message
timestamp
replyto
然后我有一个视图,它收集每个主题的最后一篇文章,并在触发器Tc_post_id上显示关于该主题的一些信息(例如,最后一张海报图像)。
最佳答案
广告1和广告2:你的数据模型很好。使用外键在这里很重要。您还需要注意的一件事是,数据库应该确保每个帖子都有一个主题记录。这是通过设置POST.topic\u id NOT NULL属性来完成的。这是数据库方面足够的安全机制,因为它可以确保没有一个帖子没有主题。不管你现在对你的文章做什么,你都有义务提供一个主题。
Ad 3:此处不建议使用带有存储过程的触发器,因为您的主题表中有其他数据(IsSticky、IsLocked等),您可能希望在创建主题记录时提供这些数据。此外,如果这样的触发器适用,则数据库设计将受到非规范化的影响。
广告4:在业务逻辑方面,您现在可以通过编写一个自动机制来帮助自己在每次创建没有指定主题id的新POST记录时创建主题记录。我建议对此使用一些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
}
}
}
关于php - 2表交互:插入,获取结果,插入,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/13905381/