How to create primary key using multiple columns & Auto increment id? - mysql

This is my tables structures
mysql> DESCRIBE sections;
+----------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+----------------+
| sec_id | int(5) | NO | PRI | NULL | auto_increment |
| sec_name | varchar(45) | YES | | NULL | |
| sec_type | tinyint(4) | YES | | NULL | |
+----------+-------------+------+-----+---------+----------------+
mysql> DESCRIBE subjects;
+-----------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+-------------+------+-----+---------+----------------+
| sub_id | int(5) | NO | PRI | NULL | auto_increment |
| sub_name | varchar(45) | YES | | NULL | |
| sections_sec_id | int(5) | NO | MUL | NULL | |
+-----------------+-------------+------+-----+---------+----------------+
mysql> DESCRIBE chapters;
+-----------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+-------------+------+-----+---------+----------------+
| chp_id | int(5) | NO | PRI | NULL | auto_increment |
| chp_name | varchar(45) | YES | | NULL | |
| subjects_sub_id | int(5) | NO | MUL | NULL | |
| sections_sec_id | int(5) | NO | MUL | NULL | |
+-----------------+-------------+------+-----+---------+----------------+
mysql> DESCRIBE questions;
+-----------------+-----------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+-----------+------+-----+---------+----------------+
| que_id | int(11) | NO | PRI | NULL | auto_increment |
| que_text | text | YES | | NULL | |
| que_created | timestamp | YES | | NULL | |
| chapters_chp_id | int(5) | NO | MUL | NULL | |
| subjects_sub_id | int(5) | NO | MUL | NULL | |
| sections_sec_id | int(5) | NO | MUL | NULL | |
+-----------------+-----------+------+-----+---------+----------------+
mysql> DESCRIBE answers;
+------------------+-----------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------------+-----------+------+-----+---------+----------------+
| ans_id | int(11) | NO | PRI | NULL | auto_increment |
| ans_text | text | YES | | NULL | |
| ans_created | timestamp | YES | | NULL | |
| questions_que_id | int(11) | NO | MUL | NULL | |
| chapters_chp_id | int(5) | NO | MUL | NULL | |
| subjects_sub_id | int(5) | NO | MUL | NULL | |
| sections_sec_id | int(5) | NO | MUL | NULL | |
+------------------+-----------+------+-----+---------+----------------+
Let's assume 'Answers' table
I created the 'ans_id' as the primary key of 'Answers' table, created a another UNIQUE key using (ans_id,questions_que_id,chapters_chp_id,subjects_sub_id,sections_sec_id)
What i want do.
create primary key for 'Answers' table using (ans_id,questions_que_id,chapters_chp_id,subjects_sub_id,sections_sec_id) columns and create Trigger before INSERT to create 'auto_increment' id.
Finally i want to accomplish this

Definition: Primary key is minimal set of attributes needed to determine every row in a table.
UNIQUE index should be {questions_que_id} + {chapters_chp_id} + {subjects_sub_id} +{sections_sec_id} and make sure it is combined as one index with these 4 columns, if you set it as different 4 indexes than you will probably achieve undesired outcome, as Zohar already pointed. From my experience, it could be unpractical to use composite keys like this. For basic table operations (CRUD) you will have to provide a lot of parameters.
Maybe to try this way: autoincremental numeric id as a primary key, the rest of important attributes as UNIQUE index. Then you could count already inserted answers to make sure right number will be assigned to ans_id. Hint: it's maybe easier to achive this from your application layer, not as a trigger or procedure for MySQL. If your users will provide answers as step-by-step, then just save a timestamp and you will know which answer is older so you don't need ans_id at all.

Related

MySQL: Trying to return NULL values in a ER model, but not having any luck

I have created a realistic table set using the ER model for MySQL. I am attempting to do joins, but seem to either be missing something, or not doing them correctly in order to produce NULL values. Below are my created tables:
+----------------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------------+-------------+------+-----+---------+-------+
| FilmNumber | char(3) | NO | PRI | NULL | |
| FilmName | varchar(60) | YES | | NULL | |
| OpeningDate | varchar(20) | YES | | NULL | |
| TopBilledActor | char(60) | YES | | NULL | |
| Genre | varchar(20) | YES | | NULL | |
+----------------+-------------+------+-----+---------+-------+
+------------------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------------+-------------+------+-----+---------+-------+
| CriticSiteNumber | char(3) | NO | PRI | NULL | |
| CriticSiteName | varchar(30) | YES | | NULL | |
| CriticName | char(50) | YES | | NULL | |
+------------------+-------------+------+-----+---------+-------+
+------------------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------------+---------+------+-----+---------+-------+
| FilmNumber | char(3) | YES | MUL | NULL | |
| CriticSiteNumber | char(3) | YES | MUL | NULL | |
| OverallScore | int(5) | YES | | NULL | |
+------------------+---------+------+-----+---------+-------+
3 rows in set (0.00 sec)
My question is, what type of join query would I need in order to produce NULL values, or does something in my table need to be modified because each of the queries I attempt do not return those values.

Need to change MUL key to PRI key

Initially the Primary Key was
(caseId,osName)
+--------------------+---------------+------+-----+-------------------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------------------+---------------+------+-----+-------------------+-------+
| createdBy | varchar(200) | NO | | NULL | |
| createdOn | timestamp | NO | | CURRENT_TIMESTAMP | |
| osName | varchar(200) | NO | | NULL | |
| caseId | varchar(100) | NO | MUL | NULL | |
| issueType | varchar(100) | NO | | NULL | |
| observationState | varchar(60) | YES | | NULL | |
| problemSolving | int(11) | NO | | NULL | |
| structure | int(11) | NO | | NULL | |
| logicalTransition | int(11) | NO | | NULL | |
| ownership | int(11) | NO | | NULL | |
| expectationSetting | int(11) | NO | | NULL | |
| empathy | int(11) | NO | | NULL | |
| valueAdd | int(11) | NO | | NULL | |
| comments | varchar(2000) | NO | | NULL | |
| version | int(11) | YES | | 0 | |
| showcase_escalate | varchar(30) | YES | | NULL | |
| ringback_state | varchar(200) | YES | | NULL | |
| trt_state | varchar(200) | YES | | NULL | |
| srp_state | varchar(200) | YES | | NULL | |
| id | int(11) | NO | PRI | NULL | |
+--------------------+---------------+------+-----+-------------------+-------+
In the above schema, id was AUTO INCREMENT. I removed that so I could make caseId as PRIMARY KEY. But since there are multiple records with same caseId I am not able to make the change.
At the end I just want caseId as my Primary Key.
Initially the Primary Key was (caseId,osName).
As defined in the MySQL Glossary:
primary key
A set of columns -- and by implication, the index based on this set of columns -- that can uniquely identify every row in a table. As such, it must be a unique index that does not contain any NULL values.
InnoDB requires that every table has such an index (also called the clustered index or cluster index), and organizes the table storage based on the column values of the primary key.
When choosing primary key values, consider using arbitrary values (a synthetic key) rather than relying on values derived from some other source (a natural key).
See Also clustered index, index, natural key, synthetic key.
Since you have multiple records with the same value for caseId, caseId alone cannot "uniquely identify every row" in your table; and therefore caseId alone cannot be a PRIMARY KEY.

mysql - adding datetime column and inserting values referenced on another table

i have a 'results' table that has a datetime colum 'created_time'.
this table reference another table 'results_values' (results.id reference results_values.results_id). here are tables describe:
mysql> describe webforms_results;
+------------------+------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------------+------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| webform_id | int(11) | NO | | NULL | |
| store_id | int(11) | NO | | NULL | |
| customer_id | int(11) | NO | | NULL | |
| customer_ip | bigint(20) | NO | | NULL | |
| created_time | datetime | NO | | NULL | |
| update_time | datetime | NO | | NULL | |
| approved | tinyint(1) | NO | | NULL | |
| view_on_frontend | tinyint(1) | NO | | 0 | |
+------------------+------------+------+-----+---------+----------------+
mysql> describe webforms_results_values;
+--------------+----------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+----------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| result_id | int(11) | NO | MUL | NULL | |
| field_id | int(11) | NO | | NULL | |
| value | text | NO | | NULL | |
| rating | int(11) | YES | | NULL | |
| created_time | datetime | YES | | NULL | |
+--------------+----------+------+-----+---------+----------------+
now i've added a datetime column 'created_time' on 'results_values', and i want to insert datetimes on the second tables copying them from the first table on the corresponding id. is there a quick way to do it?
yes triggers are the solution. And if you want to update already inserted data, you can do :
UPDATE webforms_results_values wrv INNER JOIN webforms_results wr
ON wrv.result_id = wr.id
SET wrv.created_time = wr.created_time
Create "Triggers" to update each and every update of those tables.
Please refer following URL:
Triggers

MYSQL Autoincrement reset after executing alter statement (mysql 5.0.92)

mysql> describe phppos_sales_suspended;
+--------------+--------------+------+-----+-------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+--------------+------+-----+-------------------+----------------+
| sale_time | timestamp | NO | | CURRENT_TIMESTAMP | |
| customer_id | int(10) | YES | MUL | NULL | |
| employee_id | int(10) | NO | MUL | 0 | |
| comment | text | NO | | NULL | |
| sale_id | int(10) | NO | PRI | NULL | auto_increment |
| payment_type | varchar(255) | YES | | NULL | |
+--------------+--------------+------+-----+-------------------+----------------+
After executing the below on an EMPTY table the primary key seems to be reset back to 1. Why is that? I thought that wasn't possible. This doesn't happen in mysql 5.1.54
ALTER TABLE `phppos_sales_suspended` ADD `deleted` INT( 1 ) NOT NULL DEFAULT '0',
ADD INDEX ( `deleted` );
mysql> describe phppos_sales_suspended;
+--------------+--------------+------+-----+-------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+--------------+------+-----+-------------------+----------------+
| sale_time | timestamp | NO | | CURRENT_TIMESTAMP | |
| customer_id | int(10) | YES | MUL | NULL | |
| employee_id | int(10) | NO | MUL | 0 | |
| comment | text | NO | | NULL | |
| sale_id | int(10) | NO | PRI | NULL | auto_increment |
| payment_type | varchar(255) | YES | | NULL | |
| deleted | int(1) | NO | MUL | 0 | |
+--------------+--------------+------+-----+-------------------+----------------+
Adding an index to an InnoDB table rebuilds the table. Not inheriting the old autoincrement value was a bug that's been fixed in your newer version.
http://bugs.mysql.com/bug.php?id=34920
http://bugs.mysql.com/bug.php?id=21404

MySqlcan't set a nullable column to null

I'm trying to insert a row into a table named Booklets which has a nullable column BookletSubjectID. The insert is failing because
'BookletSubjectID' cannot be null
Here's my MySQL session copied verbatim. I must be missing something really obvious, but can't see it.
mysql> desc Booklets;
+----------------------+---------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------------+---------------+------+-----+---------+----------------+
| BookletID | int(11) | NO | PRI | NULL | auto_increment |
| MemberID | int(11) | NO | MUL | NULL | |
| Name | varchar(255) | YES | | NULL | |
| Description | varchar(1000) | YES | | NULL | |
| RelationshipTypeID | varchar(12) | YES | MUL | NULL | |
| RateTypeID | varchar(2) | YES | MUL | NULL | |
| PrivTypeID | varchar(2) | NO | MUL | NULL | |
| PhotoAlbumID | int(11) | YES | MUL | NULL | |
| VideoAlbumID | int(11) | YES | MUL | NULL | |
| BookletSubjectTypeID | varchar(2) | NO | MUL | NULL | |
| BookletSubjectID | int(11) | YES | MUL | NULL | |
| Deleted | tinyint(1) | NO | | 0 | |
| Credt | datetime | NO | | NULL | |
| Updt | datetime | YES | | NULL | |
+----------------------+---------------+------+-----+---------+----------------+
14 rows in set (0.00 sec)
mysql> INSERT Booklets (MemberID, Name, PrivTypeID, BookletSubjectTypeID, Deleted, Credt)
VALUES (546502, 'dddd','pu', 'no', 1, NOW());
ERROR 1048 (23000): Column 'BookletSubjectID' cannot be null
Thanks,
Don
It seems that:
If a table has a column which is part of a multi-column primary key then that column
cannot be nullable.
See this bug report and its response.