Do underscores in a MySQL table names cause issues? - mysql

Do underscores in table names affect performance or cause issues on some platforms?
For example, user_profiles
Would it be better to use userProfiles or is it just a matter of personal preference?

Nope. Underscores are perfectly legal in table names.
This page here in the MySQL documentation tells you about what characters are allowed.
Basically:
Permitted characters in unquoted identifiers:
ASCII: [0-9,a-z,A-Z$_]
Extended: U+0080 .. U+FFFF
Permitted characters in quoted identifiers:
ASCII: U+0001 .. U+007F
Extended: U+0080 .. U+FFFF
Personally I tend to stick with lowercase a-z, the occasional number, and underscores.
But as #Vince said, it's just personal preference.

The only issue I've seen is that when using mysqlshow to view the structure of a table it appears to treat the underscore as a wildcard and returns only matching table names if there is an underscore in the name.
I could find no way to view the table structure of a table if there is an underscore in the name. I just discovered and confirmed this myself this morning.
I know this to be true of MySQL versions 4.0.18 and 4.1.22 for older versions and 5.1.52 for newer. Perhaps this is documented somewhere (I haven't taken the time to look yet), but it might be a perplexing thing for others, so I decided to mention it when I ran across this question when looking for information on the problem myself.

There's nothing wrong with using underscores, but keep in mind there may be occassions you need to escape the underscore, e.g. My\_Table

I found a few links to MySQL bugs that have either been marked closed or can't reproduce regarding underscores. As far as I know there are no issues - I always use underscores over camel-case and haven't experienced any problems.

No, it's perfectly good. In fact, it is the most recommended naming from MySQL (based on who they name their internal tables!).
Be aware that naming that in Microsoft Windows the default MySQL behaviour is to lower-case your table names. This may cause problems. I am not sure what causes this.
However I personally prefer to name my tables like UserLikesPage, User and PostComment for example, since it reflects the class name in my code and I don't use Windows with MySQL.

You should avoid it. Although it is a permitted character in MySQL documentation, it appears it might cause trouble. For example, in MySQL 5.0 & 5.1 (and may be later versions), the query cache is never hit for queries involving a table name containing an underscore.

Nope, underscores in a database never cause any issues at all.
My experience say that it is a better idea to identify any words in a database column.
If we use 'thisIsMyColumn' as a column name it's easy to write them,
but 'this_is_my_column' as column name is more readable than the previous one.

There is no problem using underscores. I think it is just personal preference.

Many database visualization tools such as SQuirreL SQL and DbVisualizer also treat the underscore as a wildcard of sorts, grouping tables "matching" into a tree. For example, a table "document_a" and related tables "document_a_details", "document_a_history". In DbVisualizer, looking at the "document_a" table shows columns for all three tables.
This is generally not a problem, but can be confusing. For example, using SQuirreL SQL's graphing tools to generate ERDs combines columns from multiple tables into a single table and draws connectors for the relationships of all of these columns in the ERD. This results in relationships being drawn that don't actually exist.
For this reason, I would not include underscores in table names.

I never had issues with underscore when naming my tables. It's just personal preference.

You can simply add grave accent (`) before and after column name. For example:
CREATE TABLE USERS(
`PERSON_ID` NVARCHAR(100),
`FNAME` NVARCHAR(255),
`LNAME` NVARCHAR(255),
PRIMARY KEY (`PERSON_ID`)
);

Related

SQL- Insert Into PHP-prepare Statement False Syntax [duplicate]

May be this question has been answered before but I couldn't find it.
I am using a 2/3 yr old MySQL database which has hyphens in its column names. When I try to use these names from my Java code, the names are broken at the hyphen (e.g. air_port becomes air) and thus are not found. I tried replacing hyphens to underscores in my code hoping that the DB might treat them equally but that doesn't work.
How can I escape the hyphen or how can I access these columns ? Could this be an issue of the character set being used ?
enclose the names within `back-ticks`
Do you have hyphens (-) or underscores (_) in your column names?
Hyphens are a big problem because if you end up mapping a column name to a variable, most languages do not like to have hyphens inside variable names. Perhaps you are using one of the Java libraries that automatically generates variables or objects whose names are based on column names.
Depending on the nature of your problem, there are a couple of different approaches you can use:
Rename all of your columns using ALTER TABLE. Be conscious that this could affect referential integrity or other applications that depend on the database. If you don't know what that means, don't do it.
Create SQL views that simple restate the tables you need but with "better" column names. This is not very efficient, but it will allow you to get what you want.
Use the AS keyword when running your SELECT statements to rename columns within queries.
None of these are great solutions, but they should get you started. Good luck!
It's better to not use hyphens in your column names. I suffered a big problem with JOIN statements where hyphens caused big trouble - there even escaping names in back ticks didn't work.
Convert the column names to use underscores - this is the safest way to go.
As an alternative - in case where even backticks should cause problems (you know it happend to me) and you want to stick to hypens no matter what - just create a VIEW to reflect the same table with all the fields and query the view instead of the original table.
Hyphens in database names aren't good also. But you can use them with the backtick trick `
`name-with-hyphen`
This entry at the MySQL forum suggests that you might have a problem. However, I think it's referring to data and not column names.
This says "don't do it." Don't know how authoritative it is.
I had to create a db named pre-ca_db.
I solved the problem with
create database `pre-ca_db`;
Good luck!

How to find if a column name is a reserved keyword across various databases

We have a legacy schema file which has the following column names, would like to understand if any of them would cause an issue if we port our application to h2, mysql, postgres or oracle.
e.g how would I know if using this would be ok across the databases listed below. Are there any good tools which can do a preliminary check on this?
key
when
size
type
count
from
with
Should be quite easy to get the list of reserved words and build a table of the reserved words. Here are some lists of reserved words:
Oracle: http://download.oracle.com/docs/cd/B19306_01/em.102/b40103/app_oracle_reserved_words.htm
SQL Server:
http://msdn.microsoft.com/en-us/library/ms189822.aspx
PostgreSQL:
http://www.postgresql.org/docs/current/static/sql-keywords-appendix.html
MySQL:
https://dev.mysql.com/doc/refman/5.6/en/keywords.html#keywords-in-current-series
And here's an online checker: http://www.petefreitag.com/tools/sql_reserved_words_checker/?word=on
I am not aware of any tables but it should not be difficult to filter them if you have the list of table names and column names.
Oracle has a V$RESERVED_WORDS view in its data dictionary.
All you have to do is to match your table/column names against this: Just add them to temp table and join with tis view. If you have a result for your query then you have a reserved word.
Other databases may have such metadata as well.
DatabaseMetaData.getSQLKeywords() is supposed to return a comma-separated list of reserved words within this database. This list doesn't contain ANSI SQL keywords such as FROM however. I'm not completely sure if this really contains all keywords in all databases however.
For H2, the list of keywords is documented under Keywords / Reserved Words.
The easiest way to find out would be to try it. All of the database management systems you mention are open source or free to download and try. Run your SQL script with the CREATE TABLE statements through them and see what happens.
The problem with asking this without reference to an actual SQL script is that some parsers have various classes of reserved words. Some key words might be listed as key words, but might still be OK to use as column names, but perhaps not in tricky SELECT statement later on. So it's always best to try it out.
I suggest based on the list you give, it won't work in most SQL systems. But you can always consistently double quote the identifiers to steer clear of key word problems. (You will need to run MySQL in ANSI mode, though.)

Should I use backticks or not when escaping keywords in MySQL?

Should all table names in MySQL be enclosed in backticks (`) to prevent collisions with reserved keywords? The reason I ask is because their use makes the SQL less portable as not all databases allow backticks.
So would avoiding table and column names containing keywords be a better course of action? If so what can be done to mitigate the risk of MySQL adding a new keyword in the next version that might collide with your schema.
Is there a best practice regarding this?
The most portable way (between the systems) is to use double quotes, however, it would require enabling ANSI_QUOTES which is off by default on most installations.
So while keeping arguably useful compatibility between different engines (and incompatibility does not limit itself to backticks only but to zillion other things different between MySQL and other systems) you are killing the compatibility between different setups of MySQL which is by far more important.
Avoiding the reserved keywords is always the best solution.
This is a matter of opinion. But portable code outweighs their use. As you noted, backticks can allow you to use reserved words, which is never a good thing. That, for me, already proves they do more harm than good.
So would avoiding table and column names containing keywords be a better course of action?
In short, yes. And there isn't much you can do with respect to future keywords except avoiding obvious candidates, e.g. with, window, over, etc.
One common practice is to prefix all your table names with a few letters and an underscore. It prevents collisions if you need to house two different applications in the same database, and you'll likely never run into reserved words.
Not escaping and manually avoiding reserved name collisions with keywords can be quite a tedious endeavor as reserved names vary greatly across databases. E.g you can use User in MySQL but not on MSSQL.
It also boils down to what the SQL queries are aimed at: are they table creation queries? initialization queries? "regular" queries? This is important as there are other factors that will make the SQL database dependent (e.g the use of AUTO_INCREMENT when creating a table).
It also depends if it is handwritten SQL files that you load and run directly into the database or programmatically constructed/filled ones. In the latter case I would use available facilities or write a micro driver that encapsulates database dialect specificities. We're not talking ORM here, just something that will help encapsulate this problem away.
To me the answer "try to avoid them" is a path of least resistance solution that might or might not bite you back at some point depending on the role of your queries. Maybe your question is a bit too broad?
I don't worry much about portability issues that can be handled with automation.
Standard SQL doesn't have any use for backticks. So can't backticks in DDL simply be replaced globally with SQL-standard double quotes? If so, that's just a one-liner in a make file.
If you use backticks, you avoid that your code stops working if MySQL introduces a new reserved keyword. Imagine all the websites you created, all stopping to work because a MySQL update introduced a new keyword that you previously used as a table name!
Your SQL may be slightly less portable, but really.. replacing a backtick with a double quote is a matter of a single search/replace in a file (unless you are using also the PHP backtick execute operator in the same file). You can't do this in reverse: replace double quotes to backticks, as other strings may be changed too (all to the PHP "execute" operator, ugh!)!
Or if you want the code to be compatible with both you can do the replace inside a few functions that process/prepare the SQL:
function myExecute($sql,$params) {
if(NOT_MYSQL) $sql=str_replace('`','"',$sql);
return execute($sql,$params);
}
What you should NEVER do is using double quotes to enclose string values in SQL. It is allowed by MySQL, but very bad for portability. You may have to replace all your strings manually.
<?php
// Don't. Use ' for strings instead
$sql='SELECT "col1" FROM "tab" WHERE "col2"="very bad"';
// Better
$sql="SELECT `col1` FROM `tab` WHERE `col2`='not that bad'";
// May crash later if tab becomes a keyword (or col1, or col2,..)
$sql="SELECT col1 FROM tab WHERE col2='not that bad'";
// Standard. But harder to replace ""s to ``s later, and annoying \'s in code
$sql='SELECT "col1" FROM "tab" WHERE "col2"=\'not that bad\'';
// Safe. Annoying.
$sql="SELECT my_unique_col1 FROM my_unique_tab WHERE my_unique_col2='not that bad'";
?>
As you see in the last example, you can name your tables and fields in a way that is probably unique (add some prefix to all, in this case "my_unique_") it is boring but mostly safe and portable.

MySQL - Necessity of surrounding table name with ` (tickmarks)?

In MySQL, is it necessary to surround tablenames with the tickmark? I've often seen code snippets that use the tickmarks, but I've not encountered a case where not surrounding a tablename with the tickmarks does anything different than with.
It looks like the framework I work with automatically parses reserved word keynames with tickmarks.
The tickmarks are there to distinguish the table (or column!) names from SQL reserved words. For example, without the tickmarks, a table or column named update could clash with the SQL command update.
It's best practice not to name tables and columns with reserved words in the first place, of course, but if you port an application to a new database engine (or possibly even a new MySQL version), it might have a different set of reserved words, so you may have just broken your app anyway. The tickmarks are your insurance against this sort of oops.
Tickmarks are necessary when table or column names use mySQL keywords.
I once worked at a job where they had a database of "locations". They called it states. and had everything in tables each table was named by state code. so Missouri was MO, and Arkansas was AR.
Several state codes are also reserve words OR ( Oregon), and IN (Indiana), and ON (Ontario) ... I know not exactly a state.
Even tho I think there were better ways of organizing their database data, there are cases where people want to name things a reserved word. This is an example where the `` marks kept code working.
It's only necessary if your table name is composed of non-"word" characters (ie: anything besides letters, numbers, and underscores), or happens to be the same as a keyword in MySQL. It's never "bad" to quote the name, but it's bad not to when you have to, so many programs that generate MySQL queries will be conservative and quote the name -- it's just easier that way.

Hyphens in column names in MySQL DB

May be this question has been answered before but I couldn't find it.
I am using a 2/3 yr old MySQL database which has hyphens in its column names. When I try to use these names from my Java code, the names are broken at the hyphen (e.g. air_port becomes air) and thus are not found. I tried replacing hyphens to underscores in my code hoping that the DB might treat them equally but that doesn't work.
How can I escape the hyphen or how can I access these columns ? Could this be an issue of the character set being used ?
enclose the names within `back-ticks`
Do you have hyphens (-) or underscores (_) in your column names?
Hyphens are a big problem because if you end up mapping a column name to a variable, most languages do not like to have hyphens inside variable names. Perhaps you are using one of the Java libraries that automatically generates variables or objects whose names are based on column names.
Depending on the nature of your problem, there are a couple of different approaches you can use:
Rename all of your columns using ALTER TABLE. Be conscious that this could affect referential integrity or other applications that depend on the database. If you don't know what that means, don't do it.
Create SQL views that simple restate the tables you need but with "better" column names. This is not very efficient, but it will allow you to get what you want.
Use the AS keyword when running your SELECT statements to rename columns within queries.
None of these are great solutions, but they should get you started. Good luck!
It's better to not use hyphens in your column names. I suffered a big problem with JOIN statements where hyphens caused big trouble - there even escaping names in back ticks didn't work.
Convert the column names to use underscores - this is the safest way to go.
As an alternative - in case where even backticks should cause problems (you know it happend to me) and you want to stick to hypens no matter what - just create a VIEW to reflect the same table with all the fields and query the view instead of the original table.
Hyphens in database names aren't good also. But you can use them with the backtick trick `
`name-with-hyphen`
This entry at the MySQL forum suggests that you might have a problem. However, I think it's referring to data and not column names.
This says "don't do it." Don't know how authoritative it is.
I had to create a db named pre-ca_db.
I solved the problem with
create database `pre-ca_db`;
Good luck!