INT[(SIZE)] [UNSIGNED] [ZEROFILL] A simple integer between -2147483648 and +2147483647 or, if the UNSIGNED attribute is provided, between zero and 429 crore. The ZEROFILL attribute indicates that the number should be prefixed with zeros until the number is SIZE digits in length.
DECIMAL[(M[,D])] [UNSIGNED] [ZEROFILL] M is the total number of digits and D is the number of decimals. If D is omitted, the default is 0. If M is omitted, the default is 10. decimal(4,2) means numbers upto 99.99 (and NOT 9999.99 as you may expect) can be saved. Four digits with the last 2 reserved for decimal.
VARCHAR[(SIZE)] [BINARY] A variable-length string that is a maximum of SIZE characters in length (where SIZE cannot exceed 255). Unless the BINARY attribute is provided, this data type is considered case-insensitive and obviously cannot hold binary data.
TEXT A case-sensitive string that is a maximum of 65,535 characters in length.
DATE Similar to the DATETIME data type, except without the time in YYYY-MM-DD format.
INT(n) Specifying an n value has no effect whatsoever. Regardless of a supplied value for n, maximum (unsigned) value stored is 429 crores. By default all numeric datatypes are SIGNED (allow negative values). When you add the keyword UNSIGNED, it will cause negative values to be disallowed. If you attempt to store a negative value in an UNSIGNED column, MySQL stores zero instead.
If you don't specify a DEFAULT value for a column, MySQL chooses a default for you. The value is NULL if the column may contain NULL; otherwise, the value depends on the column type. For numeric columns, the default is zero. For string columns other than ENUM, the default is the empty string. For ENUM columns, the default is the first enumeration member.
BLOB or TEXT column with a maximum length of 65,535 characters.
A SET datatype can hold any number of strings from a predefined list of strings specified during table creation. The SET datatype is similar to the ENUM datatype in that they both work with predefined sets of strings, but where the ENUM datatype restricts you to a single member of the set of predefined strings, the SET datatype allows you to store any of the values together, from none to all of them.
VARCHAR(10) column can hold a string with a maximum length of 10 characters. The actual storage required is the length of the string (L), plus 1 byte to record the length of the string. For the string 'abcd', L is 4 and the storage requirement is 5 bytes.
A varchar will take up less disk space than a char. A char is padded to fill it's length, so a index on char will be much larger than a varchar, depending on content.
varchar(n) VARCHAR is shorthand for CHARACTER VARYING. 'n' represents the maximum column length (upto 255 characters) char(n) is similar to varchar(n) with the only difference that char will occupy fixed length of space in the database whereas varchar will need the space to store the actual text. For example, a VARCHAR(10) column can hold a string with a maximum length of 10 characters. The actual storage required is the length of the string (L), plus 1 byte to record the length of the string. For the string 'abcd', L is 4 and the storage requirement is 5 bytes
If you make the column a TIMESTAMP data type and leave the default as NULL, it will automatically use the current date/time if no value is entered. Please note, this will only work this way for the first TIMESTAMP column in the table. Also, if ever you update a row containing TIMESTAMP columns, the first TIMESTAMP column will automatically be updated to use the new current date/time.
The first TIMESTAMP column of a table is updated automatically when any column is changed in the row. Another issue is the range: a TIMESTAMP column can store values between 1970 and 2037, while a DATETIME column can store values in the range from '1000-01-01 00:00:00' to '9999-12-31 23:59:59'.
A table name can have a shorter name for reference using AS. You can omit the AS word and still use aliasing. For e.g. SELECT COUNT(B.Booking_ID), U.User_Location FROM Users U LEFT OUTER JOIN Bookings B ON U.User_ID = B.Rep_ID AND B.Project_ID = '10' GROUP BY(U.User_Location)
Aliasing plays a crucial role while you are using self joins. For e.g. people table has been referred to as p and c aliases! SELECT p.name as parent, c.name as child, MIN((TO_DAYS(NOW())-TO_DAYS(c.dob))/365) as minage FROM people as p LEFT JOIN people as c ON p.name=c.parent WHERE c.name IS NOT NULL GROUP BY parent HAVING minage > 50 ORDER BY p.dob;
Rename Table syntax is: RENAME TABLE tbl_name TO new_name
If you want to swap two table names, you can do so like this:
RENAME TABLE old_table TO tmp_table , new_table TO old_table , tmp_table TO new_table ;
“ create table” using selected rows OR “insert into” the “select”ed records
The rows returned by the “select” query can be saved as a new table. For e.g. CREATE TABLE LearnHindi SELECT english.tag, english.name AS english, hindi.name AS hindi FROM english, hindi WHERE english.tag = hindi.tag
If you want an empty table just change the select to return no rows like so..
CREATE TABLE emps2 AS SELECT * FROM emps WHERE 1=2;
If the table is already present, you can use INSERT INTO table1 (feld1, field2) SELECT field1, field2 FROM table2
INSERT INTO Persons_backup SELECT * FROM Persons
INSERT INTO Persons_backup SELECT LastName, Firstname FROM Persons WHERE City=‘Delhi‘
INSERT INTO Empl_Ord_backup SELECT Employees.Name, Orders.Product FROM Employees INNER JOIN Orders ON Employees.Employee_ID=Orders.Employee_ID
CREATE TABLE emps2 AS SELECT emp_id, emp_name FROM emps;
This method will copy the column types and length but not key declarations. You will have to use alter table or create index command to add the keys. You can, however, duplicate the table with keys in a single command like this...
CREAET TABLE tblnumbers2 LIKE tblnumbers
But what if you want only a few columns from the original table?
CREATE TEMPORARY TABLE tmpRatings(KEY(map)) SELECT map , avg(rating) as rating , count(id) as votes FROM maps_rating GROUP BY map
CREATE TABLE support_cost ( serial INT NOT NULL PRIMARY KEY, sumcost INT, KEY sumcostix(sumcost) ) SELECT serial, SUM(cost) AS sumcost FROM conveyor GROUP BY serial
You can change the column definition if you do not want the same column types as the select table.
CREATE TABLE tblphone3(fname VARCHAR(30) DEFAULT NULL, lname VARCHAR(30) NOT NULL DEFAULT ‘’, KEY fname(fname)) SELECT fname, lname FROM tblphone;
MyISAM does table level locking, while InnoDB does row level locking. In addition to foreign keys, InnoDB offers transaction support, which is absolutely critical when dealing with larger applications. Speed does suffer though because all this Foreign Key / Transaction stuff takes lots of overhead.
If you are using InnoDB tables (or BerkeleyDB tables), MySQL is ACID compliant. Using the transaction syntax gives you atomicity. Transactions and foreign key constraints give you consistency. You can choose the level of isolation that transactions have from one another. The binary log and repair tools provide durability. (Using replication, you can have a highly durable system without any single point of failure.)
ACID stands for Atomicity, Consistency, Isolation, and Durability.
Each column must contain only one value (atomic or indivisible)
All columns whose values are the same across multiple rows must be turned into their own table and related back. (Primary and Foreign Keys)
Every non-key column is dependent upon the Primary Key.
1 st Normal form Each column must contain only one value Delhi 120 Sen Shantanu Calcutta 30 Sen Shantanu Calcutta 20 Oak Shantanu Mumbai 10, 90 Oak Shantanu city ordered surname name Delhi 120 Sen Shantanu Mumbai 90 Oak Shantanu Calcutta 30 Sen Shantanu Calcutta 20 Oak Shantanu Mumbai 10 Oak Shantanu city ordered surname name
2 nd Normal form All columns whose values are the same across multiple rows must be turned into their own table Delhi 120 Sen Shantanu Mumbai 90 Oak Shantanu Calcutta 30 Sen Shantanu Calcutta 20 Oak Shantanu Mumbai 10 Oak Shantanu city ordered surname name 4 3 2 1 ID Delhi Sen Shantanu Calcutta Sen Shantanu Calcutta Oak Shantanu Mumbai Oak Shantanu city surname name 120 4 90 1 30 3 20 2 10 1 Ordered ID
UPDATE sales SET Value = NULL WHERE Value = 'NULL‘; UPDATE sales SET Value = NULL WHERE Value = '‘;
SELECT SUM(Value) FROM sales WHERE Type = "Pri“;
SELECT SUM(Value) FROM sales WHERE Type = "Pri" AND `Month` IN ('April','May','June');
SELECT SUM(Value) FROM sales WHERE sales.Code = ? SELECT master.code FROM master WHERE master.Product_Name LIKE "A%“; SELECT SUM(Value) FROM sales WHERE sales.Code IN (SELECT master.code FROM master WHERE master.Product_Name LIKE "A%");
SELECT COUNT(*) FROM sales WHERE Value IS NULL;
SELECT COUNT(*) FROM sales WHERE Type = "Pri" AND Value IS NULL
SELECT (SELECT COUNT(*) FROM sales WHERE Type = "Pri" AND Value IS NULL) AS PRI_BLANK, (SELECT COUNT(*) FROM sales WHERE Type = "Sec" AND Value IS NULL) AS SEC_BLANK, (SELECT COUNT(*) FROM sales WHERE Type = "Closing" AND Value IS NULL) AS CLO_BLANK;
SELECT master.Product_Name, SUM(sales.Value) FROM sales LEFT JOIN `master` ON sales.Code = `master`.Code GROUP BY sales.Code;
When you precede a SELECT statement with the keyword EXPLAIN, MySQL explains how it would process the SELECT, providing information about how tables are joined and in which order. EXPLAIN is for query optimization analysis for e.g. EXPLAIN SELECT * FROM students
The output from EXPLAIN shows ALL in the type column when MySQL uses a table scan to resolve a query. The possible types are, from best to worst: system, const, eq_ref, ref, range, index and ALL.
Only index in the “Extra” column indicates that information will be retrieved from index file without using the dta file.
SELECT * FROM t1, t2 FORCE INDEX (index_for_column) WHERE t1.col_name=t2.col_name;
Optimize WHERE clauses by using the rule of "column operator constant"
Slow query: `birthdate` + INTERVAL 16 YEAR < NOW())
Fast query: `birthdate` < NOW() - INTERVAL 16 YEAR
The following 3 queries are better in that order… WHERE TO_DAYS(date_col) – TO_DAYS(CURRENT_DATE) < 30 WHERE TO_DAYS(date_col) < 30 + TO_DAYS(CURRENT_DATE) WHERE date_col < DATE_ADD(CURRENT_DATE, INTERVAL 30 DAY)
The following query will use indexes on date column. SELECT * FROM bills WHERE due_date BETWEEN CONCAT(YEAR(CURDATE()),'-',MONTH(CURDATE())-1,'-1') AND LAST_DAY(CURDATE())
Keep in mind EXISTS/NOT EXISTS are for SQL (Parent) Heavy queries otherwise you should use IN/NOT IN
Use of OPTIMIZE TABLE on a regular basis helps keep performance on the table from degrading.
Day is in the range 1 to 31. If so, you could save 3 bytes per row by changing day from INT (4 bytes) to TINYINT (1 byte). Similarly, you could save 1 byte per row by changing yearmonth from INT to MEDIUMINT. 4 bytes per row * 38 million rows = about 150 Mb saved. Smaller rows make disk reads faster, and require less memory to process and cache. Also, smaller columns make for smaller indexes.
Make all character columns CHAR rather than VARCHAR. The tradeoff is that your table will use more space, but if you can afford the extra space, fixed – length rows can be processed more quickly than variable – length rows.
if you are only storing positive numbers, make it unsigned, you essentially double your capacity to store positive numbers without changing the column type.
Declare columns to be NOT NULL so that the query will be faster since it need not check for NULL as a special case.
Consider using ENUM columns since ENUM values are represented as numeric values internally.
A table can have only 1 primary key, but multiple unique constraints.
Columns in primary keys must be NOT NULL.
Columns in unique keys can be NULL (if they are NOT NULL, then the unique key is functionally the same as a primary key).
Simply create a UNIQUE index on the fields which you with to be unique.
Add into your table creation the line UNIQUE (firstname, lastname)
OR Alter the table once created using: ALTER TABLE tablename ADD UNIQUE (Column1, Column2)
Define keys Before After name VARCHAR(99) NOT NULL UNIQUE surname VARCHAR(99) NOT NULL UNIQUE UNIQUE KEY (name, surname) ALTER TABLE contacts ADD UNIQUE KEY (name, surname) CREATE UNIQUE INDEX myindex ON contacts (name, surname); DROP INDEX myindex ON contacts
Keys explained Maximum key length is 500 bytes
There can only be one AUTO_INCREMENT column and it must be defined as a key.
A single column can be part of multiple keys.
Use fulltext index to avoid 500 bytes limitation or to search words those are less than 3 characters
a UNIQUE index that does not allow NULL is functionally equivalent to a PRIMARY KEY.
A key made up of more than one column is a composite key.
The keyword INDEX may be used instead of KEY.
You can name an index by including the name just before the column list.
For a PRIMARY KEY, you don't specify a name because its name is always PRIMARY.
any character-based field (CHAR, VARCHAR, or TEXT) as a FULLTEXT index
It allows for complex text searching against data stored in those fields. This feature is not to be confused with the LIKE function in MySQL. LIKE works more along the lines of a regular expression and hence may or may not take advantage of indexes. On the other hand, FULLTEXT indices are fully indexed fields which support stopwords, boolean searches, and relevancy ratings.
MATCH (E.title,E.entry) AGAINST ('+vacation -washington' IN BOOLEAN MODE)
Binary logging will record in a binary file all SQL transactions executed and attempted on the server. By using the mysqlbinlog utility, the contents of the binary log file can be extracted so that the SQL statements may easily be rerun. To enable binary logging, add the following line to your server's options file (i.e., /etc/my.cnf or c:my.ini, depending on your system) in the [mysqld] group:
log-bin = /var/log/mysql/bin.log
The exact path to use will depend on your filesystem and your preferences.
An important aspect of foreign keys is the referential action (ON DELETE CASCADE, ON UPDATE SET NULL, etc) which allow you to have the database take care of cascading actions when a parent row is deleted without having to worry about having an application programmer do it and make a coding error or forget to and leave orphaned rows.
So if you have a student parent table and an enrollment child table, you can set it to delete rows in the enrollment table for student 123 if student 123 is deleted form the student table (no orphaned rows in enrollment when a student is deleted). You can also set up referential actions to prevent deleting rows from a parent if there are rows in a child table (ON DELETE RESTRICT), it all depends on your situation.
Foreign Keys also requires that any rows inserted into the the child table MUST have a value that matches in the parent table.
So for the student/enrollment table, if you attempt to insert a row into enrollment for studentId 342, the only way that query will work is if there is indeed a student with studentId 342 in the student table. This is the "referential integrity" part of Foreign Keys.
Both tables must be InnoDB type. In the referencing table, there must be an index where the foreign key columns are listed as the first columns in the same order. In the referenced table, there must be an index where the referenced columns are listed as the first columns in the same order. Index prefixes on foreign key columns are not supported.
For e.g. No score record could be entred for a student that does not exist in the student table. In addition, we could allow cascading deletion such that if a student were deleted from the student table, any score records for the student would automatically be deleted from the score table.
Remember, the idea of SET is that you could store up to 64 values in the same column for a given row, so that you could, in theory, say that Smitty's is a combination pool hall and dry cleaner (plus up to 62 other things if the owner has some additional sidelines, like selling gardening supplies or magazines).
E.F. Codd, the guy who came up with the theory upon which all relational databases, like DB2 and MySQL, are based, would object strongly to this because his theory said that you should NEVER have more than one value in a column of a given row.
Now, a quick discussion of primary keys. Codd said that every table needs a primary key: a value that makes each row of a table unique from all of the other rows in the table.
You could think of the Business_Type_Lookup table as a sort of spell-checker; if it is turned on, then the only values which can go in the business_type column in the Business_Types table are values that are in the business_type column of the lookup table. Therefore, if the lookup table listed only the values 'pool hall', 'dry cleaner' and 'restaurant', those are the only values that could ever be put in the business_type column in the Business_Types table.
A foreign key is a column in one table that gets its value from a column in ANOTHER table. In this case, our foreign key is the business_type column in the Business_Types table. That's why it contains a FOREIGN KEY clause that refers back to the lookup table's primary key. If the lookup table contains only the values 'foo', 'bar' and 'squeak', then only those three business types can appear in the Business_Types table. This, in effect, is the activation of the 'spell-checker'.
The beauty of this is that the enforcement of these values is done entirely by the database; you don't have to write any application code to do it. If you try to insert a value in the Business_Type table that isn't in the lookup table, the DATABASE detects this and refuses with a message that tells you what you tried to do wrong. That's why I think lookup tables are a better approach than the 'SET' datatype.
Oh, one small thing. Since MySQL isn't fully mature yet, foreign keys only get enforced between tables that use the InnoDB engine; therefore, each of our tables should have 'TYPE=InnoDB' in the definition.
MySQL will use only one index per query. So having more indexes doesn’t always help.
Creating a key will make the query execute very fast, but if that is the only reason for the key you are going to be trading quite a lot of space for the speed of one query. How often are you going to run this query? If you have 324 million rows, then that index is going to consume somewhere in the order of 2G or more of disk space. Is it worth using all that space to make one query faster?
If a table has 1,000 rows, this is at least 100 times faster than reading sequentially. Note that if you need to access almost all 1,000 rows, it is faster to read sequentially, because that minimizes disk seeks.
MySQL uses multiple-column indexes in such a way that queries are fast when you specify a known quantity for the first column of the index in a WHERE clause, even if you don't specify values for the other columns.
/* create table syntax should have fulltext(title,body) defined */ SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('india');
When specifying an index for TEXT and BLOB types, you must specify a length. as an example... CREATE TABLE test (sValue TINYTEXT NOT NULL, UNIQUE KEY(sValue(90))) CREATE INDEX part_of_name ON customer name(10))
Possible indexes on 3 column table Index a,b,c in that order cover the single column index on ‘a’ as well as ‘a,b’
We also want to search by: Customer name (last, first) City, state Postal (zip) code Address
Index the name, city/state, zip and address Four indexes: slow insert, update, delete, but fast lookup If customer database is fairly stable, this is fine Similar logic for parts catalog, bill of materials, etc.
Index every word in the entire database; count occurrences and rank matches.
Recent advances (frequency of links, usage) enhance this.
Avoid single column indexes whenever practical. Most useful indexes contain from 2 to 5 fields.
Don't forget that PRIMARY keys and UNIQUE constraints are also indexes.
Design your indexes after your most common or frequently used query patterns. Analyze your WHERE clauses first, then look at speeding up certain queries by considering values in your ORDER BY clauses.
Learn how to use EXPLAIN. It will give you excellent advice on how to help your queries.
If the query doesn't use the index then you could use the FORCE INDEX to ensure it does. The FORCE INDEX is only there as of 4.0.9, if that can't be used then try USE INDEX.
Function call or an arithmetic expressions on a columns prohibits it from using indexes. In short, indexes are not used if you are using functions like lower(col_name) while comparing the text. You will need to reorganize the query, if possible, to take advantage of indexes.
A column that has ‘yes’ or ‘no’ for content won’t be improved by indexing. On the other hand, a column where the values are unique (for example, Social Security Number) can benefit greatly from indexing.
The smallest or largest value for an indexed column can be found quickly without examining every row when you use the MIN() and MAX() functions.
MySQL can often use indexes to perform sorting operations quickly for ORDER BY clause
Sometimes MySQL can avoid reading the data file entirely. Suppose you’re selecting values from an indexed numeric column and you’re not selecting other columns from the table. In this case, by reading an index value, you’ve already got the value you’d get by reading the data file. There’s no reason to read values twice, so the data file need not even be consulted.