我正在建立一个网站,该网站将托管我自己编写的一些书籍。书籍内容将作为HTML块存储在数据库中。
一本书包含几个章节,每章包含几个章节。我决定给每本书,章节和章节提供唯一的ID:s,目的是我可以自由移动和删除部分,而不必更新记录。
所以数据库看起来像这样:
books:
book_id int
book_name varchar
chapters:
book_id int references books.book_id
chapter_id int
chapter_no int
chapter_name varchar // will probably be factored out to a separate table
sections:
chapter_id int references chapters.chapter_id
section_no int
section_id int references section_texts.section_id
section_texts:
section_id int
section_text text
因此,例如,第3章中的第5节可以指向section_text
section_id
79,并包含文本“Hello world!”。第6节可以有section_id
83等等。
现在我想创建一个PHP方法,根据书名,章节编号和章节编号,为我检索section_text
。我现在所做的只有4个步骤:
function getText($bookName, $chapter, $section)
{
// retrieve book id
$query = $this->db->query(
sprintf('SELECT book_id
FROM books`
WHERE book_name = %s;', $bookName));
$row = $query->row();
$bookId = $row->book_id;
// retrieve chapter id
$query = $this->db->query(
sprintf('SELECT chapter_id
FROM chapters`
WHERE book_id = %d AND chapter_no = %d;', $bookId, $chapter));
$row = $query->row();
$chapterId = $row->chapter_id;
// retrieve section id
$query = $this->db->query(
sprintf('SELECT section_id
FROM sections`
WHERE chapter_id = %d AND section_no = %d;', $chapterId, $section));
$row = $query->row();
$sectionId = $row->section_id;
// retrieve section text
$query = $this->db->query(
sprintf('SELECT section_text
FROM section_texts`
WHERE section_id = %d;', $sectionId));
$row = $query->row();
return $row->section_text;
}
因此,对于上面的示例,调用getText("testBook", 3, 5)
应该返回检索到的文本,即Hello World!
。
虽然它有效但似乎是错误的方法,创建4个查询以获取一个部分。这将是一个小型网站,因此性能不是问题,但我仍然对如何改进它感兴趣。
答案 0 :(得分:1)
因此,从名称所需的书开始,如果章节与给定章节匹配,请将章节连接到该书上,如果章节ID与给定章节匹配,则将章节连接到该章节,然后从中选择html那部分。
要想象..从所有书籍开始,过滤除了你想要的书之外的所有书籍,然后加入所有章节,过滤掉你想要的章节(再留下1行),然后加入所有章节,并过滤掉你想要的部分(再次,剩下1行),然后从第1行获得你想要的任何信息。
答案 1 :(得分:1)
你应该看看的函数叫做“JOIN”,它允许你在一个语句中逻辑连接两个表。 (请参阅MySQL Reference或Wikipedia: JOIN)因此,您的示例可能如下所示:
SELECT section_texts.section_text
FROM section_texts st
JOIN sections s ON st.section_id = s.section_id
JOIN chapters c ON s.chapter_id = c.chapter_id
JOIN books b ON c.book_id = b.book_id
WHERE b.book_id = <book-id>
AND c.chapter_no = <chapter>
AND s.section_no = <section>;
最后,我没有看到分隔section和section_texts的理由。为了保存一个JOIN-Operation(并且因为它无论如何都是关于同一实体的1:1-Relation),尝试将section_text-Column合并到sections表中,从而删除section_texts-Table。
希望有所帮助!