-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Building and Querying Multilevel Heirarches #2965
-
More of a general SQL question here, but I use your browser almost exclusively for my work now, and I'm stumped. I'm also not an SQL guru, but more of a newbie and hobbyist, who got in over his head. If you like teaching, then I'm your student.
Am trying to build and query a multilevel heirarchical database four or five levels deep for a book, so the hierarchical structure would be something like:
- Title
-
- Chapters
-
-
- Subchapters
-
-
-
-
- Paragraphs
-
-
I have seen varying structures for how this might be setup. Some use one tables; others could use several tables. Additionally, some use joins; others use subqueries. And, finally, I think the problem is generall handled using taxonomy - although I dont know if that is exactly right or how it works.
What I am seeking is a solution, but a full lesson on how to do this might not be so practical here. It usually helps if I have a good example to work off of an play with.
Can anyone here provide some pointers on how to set up and run something like this?
Ty!
Beta Was this translation helpful? Give feedback.
All reactions
Replies: 2 comments 2 replies
-
Whats the end goal - if a paragraph is 'all bananas are yellow' and the user types 'banana' then it's got to display the title? Or is it if they type 'bananas' then it displays all paragraphs, related chapters, 'see also's', etc...
The former is relatively easy ... the latter is harder.
Relational data just means there is a link from one piece of information to another. The simplest example is addresses.
Rather than storing an address 'as is', the country is farmed off into another table. I'm based in the UK, so we have roads, towns and counties - again, similar to your books hierarchy. A town must be in a county, and a road must be in a town. Well, 99% of the time.
So rather than 'My town' being in every record row, we just store the town as being record number 3. Another table has a row of towns, with 'My town' being #3. The idea being storing '3' is more efficient than storing 'My Town' each time, and prevents data errors of 'Mmmy TTown' being entered for a town. Rebuilding this address back out is very easy, using joins as you mentioned. A join is simply linking the tables together using their relation - so address having 'town #3' linking with the table holding that record.
To get the best schema for your database, we just need to confirm your goals.
Beta Was this translation helpful? Give feedback.
All reactions
-
The best way to describe the goal would be to say something like, "I would like to query the DB to read whats written in the DB like a book". So, if you opened a hardcopy book, you could see the table of contents on one view; or, if you opened it to the start of a chapter, you could see the title in a header and the paragraphs; or, if you just wanted to look at a paragraph, you could do that too. I guess basically, I want to think of my queries like turning through pages in a book, if that makes any sense.
The only thing in addition would be to add stuff into the book bc this evolved out of a personal journal. What I am trying to do is add something like a framework around what I have written, such as would be a Table of Contents, but I also want to add to it, too.
I did find a free DB setup in mysql for like what I am describing, but it will require some revision because sqlitebrowser use sqlit3, and it doesnt add info to the database. If you know of Paul DuBois (of Perl fame), he has a free copy of the KJV Bible.
http://www.kitebird.com/mysql-cookbook/downloads-3ed.php
(See the "The mcb-kjv distribution is used for the KJV FULLTEXT examples discussed in the book." section of the page and its downloads.)
The SQL for the book's build is divided into a kjv.sql and a kjv_bookmap.sql. The kjv.sql is the bible in one table. I dont completely understand the kjv_bookmap.sql file, but it seems to simply divide the DB/Book up into the Old and New Testaments. Text files contain the content. The perl scripts are not directly relevant, but they do contain some possibly helpful SQL.
The software is trustworthy, as DuBois is a well known writer, but I havent tested it yet.
I am trying to get it to run in DB Browser right now, but having some problems. It would be fun to practice my queries to "read the database like a book", but I'm still trying to get it setup. I dont have time to read the book, but I also dont understand why he put everything in one table versus spreading it out across many tables. I would have spread it out and used joins - perhaps erroneously on my part - although I tend to think the "join" approach would allow for a faster, more robust solution. The other thing about this example is, the book is already written, whereas I am looking to parse my writings, but also to insert more information to my journals. I dont understand how I would access all those foreign keys to reinsert them later on to keep my point of reference in focus, especially if I used the join approach.
In any case, the drivers and data are there on his site, if you wish to deep dive into it. But I will post the MySQL commands at least for the setup here. I just want to get the build to work in DB Browser right now, so then I could at least try to get to practicing some of the selection queries.
# kjv.sql
# Table to hold verses of the King James Version of the Bible
# Table is created explicitly as MyISAM because any MySQL server
# should support FULLTEXT indexes for MyISAM tables. If your server
# supports FULLTEXT for InnoDB (MySQL 5.6 or higher), you can modify
# the ENGINE clause to ENGINE = InnoDB.
DROP TABLE IF EXISTS kjv;
#@ _CREATE_TABLE_
CREATE TABLE kjv
(
bsect ENUM('O','N') NOT NULL, # book section (testament)
bname VARCHAR(20) NOT NULL, # book name
bnum TINYINT UNSIGNED NOT NULL, # book number
cnum TINYINT UNSIGNED NOT NULL, # chapter number
vnum TINYINT UNSIGNED NOT NULL, # verse number
vtext TEXT NOT NULL, # text of verse
FULLTEXT (vtext) # full-text index
) ENGINE = MyISAM; # can be InnoDB for MySQL 5.6+
#@ _CREATE_TABLE_
# Add other indexes to the kjv table, to help queries that
# search on other columns
ALTER TABLE kjv
ADD INDEX (bnum),
ADD INDEX (bsect),
ADD INDEX (cnum),
ADD INDEX (vnum);
# kjv_bookmap table used by kjv.pl script
# bsect is O = Old Testament, N = New Testamant, A = Apocrypha
# bnum is the book number. This actually is sufficient to
# identify any book. (The section isn't needed.)
DROP TABLE IF EXISTS kjv_bookmap;
CREATE TABLE kjv_bookmap
(
bsect ENUM('O','N','A') NOT NULL # book section
bnum TINYINT UNSIGNED NOT NULL, # book number
bname CHAR(40), # book name
INDEX (bsect),
INDEX (bnum)
);
Beta Was this translation helpful? Give feedback.
All reactions
-
BTW, Is there some kind of a conversion app to take MySQL statements and translate them into sqlit3 commands?
Beta Was this translation helpful? Give feedback.
All reactions
-
Is there some kind of a conversion app to take MySQL statements and translate them into sqlit3 commands?
Yes, as both use SQL which is pretty much standard. There are slight tweaks, as mySQL uses various datatypes (eg, date) which SQLite doesn't use - it only has numbers, text and blob (ignore blobs for most instances).
Not that it matters, but the comments refer to MyISAM, but InnoDB is far superior and should be used instead. But that's digressing slightly.
Beta Was this translation helpful? Give feedback.