What I\'m looking for is a breakdown of table names w/ corresponding fields/types.
The bible I want to store will be in English and needs to support the following:
Mark Rushakoff's answer is probably the best for you specific need. However more generally if need to store content that either has data within the content or if you need to store data about the content a Content Management System is typically used. You can build your own (which WernerCD's answer had a table structure for) or use a CMS product. The list here shows the wide variety of technologies used (around 30 in this list use MySQL)
Here is another collection / example for you:
https://github.com/scrollmapper/bible_databases
Here you will see SQL, XML, CSV, and JSON. Of special note is the cross-reference table (quite extensive and amazing) and a simple verse-id system for fast queries.
EDIT: Notice the ids of the tables are book-chapter-verse combinations, always unique.
SQL is the BEST way to store this. Considering your requirement we can split them into two major parts
Information that's dependent on individual version
Information that isn't dependent on individual version
For various reasons I prefer to store the whole bible project into one SINGLE table, Yes call it as bible
For your visual here is my screen I have stored nearly 15 versions of bible in single table. Luckily the different version names are just kept as column wide. When you add more version in future your table grows horizontally which is okay thus the # of rows remain constant(31102). Also, I will request you to realize the convenience of keeping the combination of ('Book, Chapter, Verse') as the PRIMARY key because in most situations that's the look-up way.
That said here is my recommended table structure.
CREATE TABLE IF NOT EXISTS `bible` (
`id` int(11) NOT NULL AUTO_INCREMENT, --Global unique number or verse
`book` varchar(25) NOT NULL, --Book, chapter, verse is the combined primary key
`chapter` int(11) NOT NULL,
`verse` int(11) NOT NULL,
`section_title` varchar(250) NOT NULL, -- Section title, A section starts from this verse and spans across following verses until it finds a non-empty next section_title
`foot_note` varchar(1000) NOT NULL, -- Store foot notes here
`cross_reference` int(11) NOT NULL, -- Integer/Array of integers, Just store `id`s of related verses
`commentary` text NOT NULL, -- Commentary, Keep adding more columns based on commentaries by difference authors
`AMP` text NOT NULL, -- Keep, keep, keep adding columns and good luck with future expansion
`ASV` text NOT NULL,
`BENG` text NOT NULL,
`CEV` text NOT NULL,
PRIMARY KEY (`book`,`chapter`,`verse`),
KEY `id` (`id`)
)
Oh, What about the Small caps and Red letters?
Well, Small caps & Red letters you can store in version columns using HTML or appropriate formats. In the interface you can strip them off based on user's choice whether he requires red letter or small caps.
For reference, you can download the SQLs from below and customize in your way
Bibles in SQL format
This repository contains entire Bible given in sql.
https://github.com/godlytalias/Bible-Database
Rather than reinventing the wheel, you might consider using a "Bible SDK" such as AV Bible, which stores text, formatting, verse numbers, etc. in an open, custom binary format.
I think they have everything you've listed except cross-references.
expanding the DB horizontally isn't very efficient with the potential of having very large tables and complex updates. so id, book, chapter, verse, V1, V2, V3, V4... Vn just seems to be looking at the problem like a spreadsheet rather than taking advantage of what a DB has to offer.
the references are static (book, chapter, verse) so they can be populated in one table with an id and with that you have the framework of the entire bible. the verse content can potentially have hundreds of versions so it would be better stored in its own table and linked with a foreign key to identifying the references. the structure would be primary_id, foreign_id, version, content.
now the content just fills in as needed and there is no need to have thousands of empty fields that in the future you have to go back and fill in or needing to expand the table and backfill all the existing data every time you add a new version. just fill in the verses as you get them which works better I think if you building it yourself.
This also makes sense as some versions only have the NT or some verses that they think were added later aren't available so there is no need to have empty fields you just have the data and it links to the verse reference. "version" can also be a foreign key to identify more information in the version like a publishing date or long/short name (ie. "NIV", "New International Version") This also works well when using more than one revision of a translation like the 1984 NIV vs 2011 NIV. Both can be identified as "NIV" but differ in content so the version_id can link another table with expanded information about the version it's using. Once that data is in and linked properly you can display it however you wish for example combining the publishing date/short version name making a name like "NIV1984" or have a separate column unique for a display name.
I'm not sure how red letter or footnotes could be displayed and I know sites like biblegateway have this as a toggle switch so it's nice to have the option to sort it like this. with red letters, this could be a special static identifier directly in the verse content that is parsed out later as a CSS identifier. It could be its own foreign table too but since it is so little a delimiter would be really easy. It really depends what you're using the data for and if you wanted to do queries for the red letters then it would be best as a foreign table (fast) rather then search the db for the delimiter (slow)
with footnotes, since it depends on unique content it would be best stored in its own table. how it is identified and placed in the content could use static reference points within the content like x number of characters in or x number of words in and then linked with the content using a foreign key again. So the footnote table could be something like primary_id, foreign_id, reference, footnote and an example of the data could be 2304, 452, 64, "some manuscripts don't include this". Primary key would be 2304, the foreign key that links to the content table is 452, the footnote is placed 64 characters in, and the footnote is "some manuscripts don't include this" As for the incrementing footnote like A, B, C or 1, 2, 3 all of this can be dynamically generated. If it's important to be a static letter/number then you might want to include it in the data but I would rather have good data that allows this automatically then list it as static data.
here's the hint, Don't add hundreds of columns... that would just a headache and it's spreadsheet thinking. it's better to work through the perfect queries to link tables with the right content.