需要帮助重构查询/数据库设计

时间:2012-03-11 09:57:00

标签: php mysql

我正在建立一个网站,该网站将托管我自己编写的一些书籍。书籍内容将作为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个查询以获取一个部分。这将是一个小型网站,因此性能不是问题,但我仍然对如何改进它感兴趣。

2 个答案:

答案 0 :(得分:1)

因此,从名称所需的书开始,如果章节与给定章节匹配,请将章节连接到该书上,如果章节ID与给定章节匹配,则将章节连接到该章节,然后从中选择html那部分。

要想象..从所有书籍开始,过滤除了你想要的书之外的所有书籍,然后加入所有章节,过滤掉你想要的章节(再留下1行),然后加入所有章节,并过滤掉你想要的部分(再次,剩下1行),然后从第1行获得你想要的任何信息。

答案 1 :(得分:1)

你应该看看的函数叫做“JOIN”,它允许你在一个语句中逻辑连接两个表。 (请参阅MySQL ReferenceWikipedia: 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。

希望有所帮助!