AUTO_INCREMENT in two places - php

I came across following sql statements and you can see that AUTO_INCREMENT is in two different places. Can you explain the different, I know the first one is auto incrementing id. But what does the second one mean?
CREATE TABLE `categories`(
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(100) NOT NULL,
`image_path` varchar(200) NOT NULL,
PRIMARY KEY(`id`)
) ENGINE = InnoDB;
Second statement.
CREATE TABLE `categories`(
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(100) NOT NULL,
`image_path` varchar(200) NOT NULL,
PRIMARY KEY(`id`)
) ENGINE = InnoDB DEFAULT CHARSET = latin1 AUTO_INCREMENT=4 ;
I referenced http://dev.mysql.com/doc/refman/5.0/en/example-auto-increment.html. But I couldn't find anything.

The AUTO_INCREMENT in the second statement sets the first number to be used in the id at 4.
`id` int(11) NOT NULL AUTO_INCREMENT
Sets the column name and tells the DB to auto increment the number when a new row is added.
) ENGINE = InnoDB DEFAULT CHARSET = latin1 AUTO_INCREMENT=4 ;
Sets the Engine used for the table, the charset and that it should start numbering at 4, not 1.
CREATE TABLE explains this in a bit more detail.
AUTO_INCREMENT
The initial AUTO_INCREMENT value for the table. In MySQL 5.0, this
works for MyISAM and MEMORY tables. It is also supported for InnoDB as
of MySQL 5.0.3.

Related

MYSQL table and column naming convention

I am curious to know what is best naming convention in terms of performance for mysql table names and column names. I am designing a new database for my project.
What I have used so far is use descriptive table/column names which sometimes seems long but I think it helps in easily understanding the use/function of a table.
For example see below DDL:
CREATE TABLE `product_configuration` (
`product_configuration_id` int(11) NOT NULL AUTO_INCREMENT,
`product_id` int(20) NOT NULL,
`product_size_id` int(20) NOT NULL,
`product_color_id` int(20) NOT NULL,
`price` float NOT NULL,
`image` varchar(255) DEFAULT NULL,
`locked` tinyint(1) DEFAULT '0' COMMENT '1=locked, 0 =unlocked. if locked then this row can''t be deleted/updated',
`active` tinyint(1) DEFAULT '1' COMMENT '1=active, 0=inactive and wont display on frontend',
PRIMARY KEY (`product_configuration_id`)
) ENGINE=InnoDB AUTO_INCREMENT=2342 DEFAULT CHARSET=latin1
And another DDL in which I use the primary key from above DDL as foreign key :
CREATE TABLE `product` (
`product_id` int(11) NOT NULL AUTO_INCREMENT,
`product_name` varchar(255) NOT NULL,
`product_description` varchar(255) NOT NULL,
`product_image` varchar(255) NOT NULL,
`price` float NOT NULL,
`active` tinyint(1) NOT NULL COMMENT '1=active, 0=inactive',
`date_added` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`product_type_id` int(11) DEFAULT NULL,
`date_modified` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`product_id`)
) ENGINE=InnoDB AUTO_INCREMENT=21 DEFAULT CHARSET=latin1
Basically I use singular table names with table name as prefix in most of the column names inside that table and I keep the same name and datatype for primary and foreign keys so that I can easily know which foreign key relates to which primary key/tables.
But I wonder, do using long table/column names have performance impact when database size grows. Like instead of just using "id" as primary key I am using long "product_configuration_id".
Also if I name tables/columns in uppercase and lowercase mixed like
"ProductConfiguration"
for table name and
"ProductConfigurationId"
for column name will that have any performance impact or linux/windows environment compatibility issue.
Long table and column names do not have (any significant) performance impact. All tables and column references are turned into internal locators during the compilation phase of the query. So pretty much the only impact is having to query a longer query string. The parsing part of query compilation is usually ignored from a performance perspective.
The following is opinion-based. As a general rule, I follow these conventions for naming:
Table names are in the plural, because they contain multiple entities.
Each table (almost always) has an auto-incremented numeric primary key, which is the singular form of the table followed by Id.
This column is the first column defined, so I can use order by 1 desc to get the most recent rows added to the table.
The table name is not (generally) part of the column name. I always (try to) use table aliases, so including the table name would be redundant.
Foreign key references use the same column name as the primary key they are referring to, when possible, so I can use using for joins.
I admit that these are "opinion-based", so the real answer to your question is in the first paragraph.

Unable to create a table in database

This is the query I have used for creating the table
CREATE TABLE IF NOT EXISTS `logging_api_request_js` (
`id` int(30) unsigned NOT NULL AUTO_INCREMENT,
`log_message` longtext,
`level` varchar(10) DEFAULT NULL,
`ip_address_merchant` varchar(45) DEFAULT NULL,
`ip_address_customer` varchar(45) DEFAULT NULL,
`creationTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updateTime` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=11
It showed an error Incorrect table definition; there can be only one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause
When I googled I saw that in the mysql 5.6. version this issue / restriction has been took off.But i wont be able to upgrade mysql right now.
Is there any work around for this,whith out changing the table structure to dump this using mysql?Please help.Im having little knowledge about the db operations.Do help.Thanks
You could remove ON UPDATE CURRENT_TIMESTAMP and create trigger.
DROP TRIGGER IF EXISTS `update_logging_api_request_js`;
DELIMITER //
CREATE TRIGGER `update_logging_api_request_js` BEFORE UPDATE ON `logging_api_request_js`
FOR EACH ROW BEGIN
SET NEW.updateTime = NEW.creationTime;
END
//
DELIMITER ;

Creation of a "temporary" table for daily operations?

I have a mysql table MAINLIST.
CREATE TABLE `MAINLIST` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`NAME` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`email` tinyint(1) unsigned DEFAULT NULL,
`contact` tinyint(1) unsigned DEFAULT NULL,
PRIMARY KEY (`id`),
) ENGINE=InnoDB AUTO_INCREMENT=17 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
Every day I select a subset of these and perform some operations. Right now I do this within the MAINLIST table, but I think it would be helpful for organization, readability and debugging to create a second table daily import the selected records, do the operations and then send the records back to the Mainlist table and destroy the daily table.
What is the best way to do this with mysql, or are there other ways to approach this problem? Perhaps I should not be doing this at all. I am wondering what best practices are since I'm not experienced with Db design. I am using the redbean ORM and php.

Jstree table definition

I have integrated Jstree in my application, now i want to understand different column in that table:
CREATE TABLE IF NOT EXISTS `tree` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`parent_id` bigint(20) unsigned NOT NULL,
`position` bigint(20) unsigned NOT NULL,
`left` bigint(20) unsigned NOT NULL,
`right` bigint(20) unsigned NOT NULL,
`level` bigint(20) unsigned NOT NULL,
`title` text CHARACTER SET utf8 COLLATE utf8_unicode_ci,
`type` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=13 ;
This is the default table provided by the site.
Now if want to add a node, how do i know the value for left, right and level.
This looks like a mix of Adjacency list an nested sets.
Nested sets are a better way of storing trees in a relational database.
It's hard to explain the principle you have to look here and here.
When you use nested sets you don't need parent_id.
I think jstree provided a sample table where you can choose by yourself what technique you use.
Another way of storing trees in a database would be a Closure Table.
It's my personal favourite. It's simple but powerful. But you hardly find anything about it on the net.

Timeline from 2 related tables

Let's say I have a screenshots table and a replies table. So: every screenshot can have multiple replies (one-to-many). Now, I want to create a combined timeline of the two, but in reality, they're pretty unrelated (in structure).
How can I select data from both tables, ordering by their publish time, descending; when for example, I can have a post, a few comments, then another post; because that would be how the timeline happened?
Normally selecting from both combines the tables; but I don't want that to happen. On that subject, I also need the tables to be distinguishable. Here's the structure for the tables...
--
-- Table structure for table `screenshots`
--
CREATE TABLE IF NOT EXISTS `screenshots` (
`id` int(11) NOT NULL auto_increment,
`user` int(11) NOT NULL,
`description` text NOT NULL,
`time` timestamp NOT NULL default CURRENT_TIMESTAMP,
`ext` varchar(4) NOT NULL default 'png',
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=14 ;
-- --------------------------------------------------------
--
-- Table structure for table `screenshot_replies`
--
CREATE TABLE IF NOT EXISTS `screenshot_replies` (
`id` int(11) NOT NULL auto_increment,
`user` int(11) NOT NULL,
`parent` int(11) NOT NULL,
`time` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
`text` text NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=27 ;
Note: I realize this may be a duplicate of this question but I didn't find the solution there working for me.
Thanks in advance! :)
You should use UNION in this case:
(SELECT id, time, 'screenshots' as tableName FROM screenshots)
UNION
(SELECT id, time, 'replies' as tableName FROM screenshot_replies)
ORDER BY time ASC
You can get the tablename of a field by using the mysql_tablename function in php
You can indicate the tablename as a column in the result set
Whenever I come across a problem like this, where you're finding it impossible to do something because you can't built a query which will extract the data, I have to start wondering do you have the right data model?
Start with what data you want to extract, and then build a model which allows that, not the reverse, and you'll find it much easiler in the long term, and also probably faster performance and quite often better flexibility.
Looking at those tables, I'd have to ask why have two of them? What's wrong with:
CREATE TABLE IF NOT EXISTS `screenshots` (
`id` int(11) NOT NULL auto_increment,
`user` int(11) NOT NULL,
`description` text NOT NULL,
`time` timestamp NOT NULL default CURRENT_TIMESTAMP,
`ext` varchar(4) default 'png',
`parent` int(11),
`text` text,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
That would allow you to do what you want, easily telling if it's a screen shot (if ext is set), a reply (if parent is set) or ... since the model now allows it ... a screenshot which is a reply!!!

Categories