Consistent table names to facilitate CRUD operations
| Project: | Drupal |
| Version: | 7.x-dev |
| Component: | base system |
| Category: | task |
| Priority: | critical |
| Assigned: | Unassigned |
| Status: | patch (code needs work) |
Our core table names are inconsistently named, reflecting the history of how Drupal developed. Some, e.g., 'node', are named in the singular for the object type they hold. Others, e.g., 'users', are named in the plural. Still others, notably 'term_data', have a totally custom name.
As we begin to take giant steps forward in introducing a schema system, http://drupal.org/node/136171, opening the way for a consistent Data API across all object types, a key need is to bring consistency. A one-to-one relationship between object type names and their primary tables will greatly facilitate operations like drupal_save($type, $item); where $type is e.g. 'node', with primary table 'node'.
All of which is to say, it's time to adopt consistent table-naming.
The attached patch simply renames existing tables in the singular. E.g., 'comments' becomes 'comment'. 'term_data' becomes 'term'. I've also included the joining tables mapping many-to-many relationships. We already had 'term_node'. Now 'blocks_roles', becomes 'block_role', etc.
Since table names are already enclosed in curly brackets, this change will be easy to make for module maintainers--a simple search and replace. (The only difficulty I guess will be if there are existing contrib tables with conflicting names. Update script will need to detect existing tables and rename them.)
Still to do: the update script.
| Attachment | Size |
|---|---|
| consistent-table-names.patch | 104.19 KB |

#1
I'm supportive for this. (Although, I don't think it is a showstopper for the data API to progress. I'd prefer to see us work on the data API first, and then worry about table name cleanup but I won't be picky.)
#2
Refreshing the patch after the Schema API being applied.
See http://drupal.org/node/145684 for some ideas of what this patch would open up.
#3
Oh, YES PLEASE!!! This has bugged me forever.
Adding to my "definitely test" queue. Thanks, Nedjo!!
#4
Oh, I should point out too a +1 to singular table names. There was a huge thread about table naming conventions I read a long time ago, since I'm a total sucker for that kind of stuff. ;) The consensus was that singular better because:
a) it's more consistent (for example, should the bridge table between users and roles be user_roles or users_roles or..?)
b) it's easier for non-English people to grasp, as they don't have to remember weird pluralization rules in English (boxES vs. blockS).
c) it makes more sense in most queries; you want to select a name from a particular user, not a name from all of the users (generally speaking).
#5
Ok re-rolled with a few fixes:
I went around and clicked on most things and seemed to go ok. Definitely could use another set of eyes, though.
Also, an update path is missing. I need to read up in the documentation to figure out how to write that.
#6
And for those following along at home, here are the name changes:
blocks => blockblocks_roles => block_role
boxes => box
comments => comment
files => file
file_revisions => file_revision
filters => filters
filter_formats => filter_format
languages => language
menu_links => menu_link
node_comment_statistics => node_comment_statistic
node_revisions => node_revision
poll_choices => poll_choice
poll_votes => poll_vote
profile_fields => profile_field
profile_values => profile_value
sequences => sequence
sessions => session
term_data => term
users => user
users_roles => user_role
vocabulary_node_types => vocabulary_node_type
This will break approximately every snippet in the handbook. ;) However, it makes the data schema FAR more consistent and easy to grok for new developers, and provides a consistent means to handling the Data API, through clever introspection.
#7
Thanks Angie! That was just the careful attention and fixing up the patch needed.
For the update, I'm not exactly sure what we need to do. Here's a suggested approach:
* Change names of all existing tables. Do this update in system module, so that it's run before other modules' updates. We have a relevant snippet from content.install:
<?php
foreach ($rename as $old_name => $new_name) {
switch ($GLOBALS['db_type']) {
case 'mysql':
case 'mysqli':
$ret[] = update_sql("RENAME TABLE {". $old_name ."} TO {". $new_name ."}");
break;
case 'pgsql':
$ret[] = update_sql("ALTER TABLE {". $old_name ."} RENAME TO {". $new_name ."}");
break;
}
}
?>
* Use the new names for all post-5.x updates in all modules' install and update functions. For example,
php_install()includes handling of existing filter formats. I included one update function in the table name changing,locale_update_6001().)Does that sound right?
I also wondered above about how to handle the case that the new names are already taken by contrib modules' tables, and suggested we simply rename those existing tables. Does that sound right?
(I'm unassigning myself in the hope I can leave this in your capable hands, but do let me know if there's ore I can do :) )
#8
no, I think the update paths are different now, post-schema patch. I'll try and find out. :)
We'll also need to update the sequences table so that {node_revisions}_vid, for example, becomes {node_revision}_vid.
The whole 'renaming takes a name already taken by contrib' is... interesting. I hadn't thought of that. but yeah, probably something like check first if the table exists. If so, output an error and don't attempt the rename until it's resolved?
#9
As long as we don't go the Rails direction with a giant pluralization dictionary (and this patch doesn't), this sounds like a good idea.
#10
See this patch http://drupal.org/node/147285 to add
db_rename_table(), which would be useful here.#11
i think this would be a good change. it was a bit frustrating initially trying to remember the table names. i just hope the files patch that renames file_revisions to upload sticks before this.
#12
I'm thrilled to see this patch!
I actually rolled a patch to rename all the core tables about a month ago, but then when I started addressing the problem of doing the update from D5 to D6, I very quickly realized that was the hard part. :-)
Whatever renames the tables has to operate in such a way to not interfere with the many other updates that need to run, as well.
I'm rather of the mind that contrib modules which conflict with renamed core database tables need to be altered to avoid the collision.
Actually, I also rather like the idea of making the table naming convention a hard and fast rule for contrib, too. If you write a module and use a table name that's plural, your module doesn't get published. But I'm sure there will be little support for that, nor any easy way to automate it. At least it should be so documented in the coding standards. Consistency really reduces effort, errors and improves quality, which is why we have coding standards, right?
Nedjo++ !
#13
Massive hunk failures.
#14
Ah, crap. I totally meant to re-roll this but little point in it now.
Will make this my first priority for D7, aka, "The fantastically CRUDdy release." ;)
#15
postponed now is less needed, maybe when a patch needs to postponed within the same cycle. adjusted status.
#16
Bumping this, if only because I can never remember which ones are plural and which aren't, and that's annoying.
#17
Still bugs the heck out of me. :-)
#18
If we fix pluralisation, we can add something in coder.module to check this too :)
#19
Me too. But obviously, I'm not working on this anymore. :)
#20
I saw #4 'b' and my gut reaction was 'Hurrah!'. One of the joys of Drupal is the diversity of the users and contributors. On reflection though, irregularity of English pluralisation is probably not one of the highest hurdles a non-native speaker suffers.
This issue crops up in many projects, not just Drupal. Imagining the inconsistency to be about singular vs plural is to oversimplify it.
A table such as 'users' contains rows where each row describes a user. A 'menu_router' table is (I guess) so named because its purpose is to be used in routing, not because each row is a menu router.
If you want consistency you have to understand English grammar well enough to understand the role collectives play (and Fowler's Modern English Usage has seven sections in his article on this!).
So you would rename 'users' not 'user', but some choice such as 'population' or 'flock'. I'm not for an instant suggesting you do this, you'd be throwing the baby out with the bathwater. I'm just trying to explain why the original choices are not quite as illogical as they might seem at first sight.
#21
Those kind of patches tend to be giant, so I suggest splitting it up by modules, so:
system.module
actions
actions_aid
blocked_ips
files
menu_links
sessions
block.module
blocks
blocks_roles
boxes
comment.module
comments
filter.module
filter_formats
filters
node.module
node_revisions
poll.module
poll_choices
poll_votes
user.module
users
users_roles
taxonomy.module
vocabulary_node_types
#22
I've posted a patch for renaming user module tables: #330983: Rename user module tables to singular.
#23
I've forgot to enable all core modules before making the previous list. Those ones also need renaming:
blogapi.module
blogapi_files
locale.module
languages
profile.module
profile_fields
profile_values
search.module
search_node_links
trigger.module
trigger_assignments
I think splitting by module makes sense, since we only need one update function per module.
#24
Ok, block.module's tables got renamed.
I've submitted a new patch for renaming node, filter and comment module tables.
The upgrade path for user and system tables will be more difficult to write, since those tables are used for access check in update.php. So I'll work on renaming those tables on the same patch.
More coming.
#25
What is exactly the use of this? Some sort of research for a "conceptual beauty of table naming"?
I'm really -1 for all this. We shouldn't waste effort on such a trivial matter.
#26
@Damien Tournoud: Who is wasting efforts? Is it you?