Need to change MUL key to PRI key - mysql

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.

Related

Select duplicate urls?

I want to turn off .html from the category paths. When I toggle the setting off in the admin panel I get a unique constraint error. We have hundreds of categories, pages and products so finding which one or more urls are conflicting is not feasible via the admin panel. As such, I'm looking in the url_rewrite table.
+------------------+----------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------------+----------------------+------+-----+---------+----------------+
| url_rewrite_id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| entity_type | varchar(32) | NO | | NULL | |
| entity_id | int(10) unsigned | NO | MUL | NULL | |
| request_path | varchar(255) | YES | MUL | NULL | |
| target_path | varchar(255) | YES | MUL | NULL | |
| redirect_type | smallint(5) unsigned | NO | | 0 | |
| store_id | smallint(5) unsigned | NO | MUL | NULL | |
| description | varchar(255) | YES | | NULL | |
| is_autogenerated | smallint(5) unsigned | NO | | 0 | |
| metadata | varchar(255) | YES | | NULL | |
+------------------+----------------------+------+-----+---------+----------------+
I'm starting with a generic "find all duplicate rows" query and trying to build out to select request_paths if they contain .html or not, however I'm struggling with the query. Here's the generic sql:
select count(request_path), request_path, store_id from url_rewrite group by request_path, store_id having count(request_path) > 1;
I've tried variations of count(replace(request_path, '.html','')) but I'm not getting any results out (e.g. select count(replace(request_path, '.html','')), request_path, store_id from url_rewrite group by request_path, store_id having count(replace(request_path, '.html','')) > 1;).
If I had the urls:
my_slug.html
my_slug
what sql query do I need to select to get my_slug (and hopefully other row data?) from the table?

Is unique index mandatory for partitioning MySQL table?

I would like to add a partition (to part by year 2020, 2021, 2022, etc.) on the table "cns_dvc":
+-----------------------+---------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------------------+---------------+------+-----+---------+-------+
| id_dvc | bigint(20) | NO | | NULL | |
| dvc | varchar(50) | NO | MUL | NULL | |
| zone | varchar(10) | YES | | NULL | |
| date_str | varchar(50) | YES | | NULL | |
| date_prs | varchar(50) | YES | | NULL | |
| external_id | int(11) | YES | | NULL | |
| no_week | int(6) | YES | | NULL | |
| day | varchar(30) | NO | | NULL | |
| pg_avg | decimal(6,3) | YES | | NULL | |
| i_spd_avg | decimal(15,3) | YES | | NULL | |
| o_spd_avg | decimal(15,3) | YES | | NULL | |
| year | int(4) | NO | MUL | NULL | |
| month | tinyint(6) | YES | MUL | NULL | |
| month_year | date | YES | | NULL | |
| date_cns | datetime | YES | | NULL | |
+-----------------------+---------------+------+-----+---------+-------+
Find the indexes for the previous table:
+--------------+------------+------------------------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+--------------+------------+------------------------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| cns_dvc | 0 | dvc | 1 | dvc | A | 33847 | NULL | NULL | | BTREE | | |
| cns_dvc | 0 | dvc | 2 | date_str | A | 4264740 | NULL | NULL | YES | BTREE | | |
| cns_dvc | 0 | dvc | 3 | pg_avg | A | 4264740 | NULL | NULL | YES | BTREE | | |
| cns_dvc | 0 | uidx_dvc_date_cns | 1 | dvc | A | 7084 | NULL | NULL | | BTREE | | |
| cns_dvc | 0 | uidx_dvc_date_cns | 2 | date_cns | A | 4264740 | NULL | NULL | YES | BTREE | | |
| cns_dvc | 1 | month | 1 | month | A | 2 | NULL | NULL | YES | BTREE | | |
| cns_dvc | 1 | year | 1 | year | A | 2 | NULL | NULL | | BTREE | | |
+--------------+------------+------------------------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
When I am trying to add some partitions I get the following error:
ALTER TABLE cns_dvc PARTITION BY RANGE(YEAR(date_cns))( PARTITION p2020 VALUES LESS THAN(2021), PARTITION p2021 VALUES LESS THAN MAXVALUE );
ERROR 1503 (HY000): A UNIQUE INDEX must include all columns in the table's partitioning function
Should I add an unique index only on the date_cns column? If so, that column could not be unique.
Perhaps, the partition type is not the right one?
Edit:
Show CREATE TABLE cns_dvc;
+--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| cns_dvc | CREATE TABLE `cns_dvc` (
`id_dvc` bigint(20) NOT NULL,
`dvc` varchar(50) NOT NULL,
`zone` varchar(10) DEFAULT NULL,
`date_str` varchar(50) DEFAULT NULL,
`date_prs` varchar(50) DEFAULT NULL,
`external_id` int(11) DEFAULT NULL,
`no_week` int(6) DEFAULT NULL,
`day` varchar(30) NOT NULL,
`pg_avg` decimal(6,3) DEFAULT NULL,
`i_spd_avg` decimal(15,3) DEFAULT NULL,
`o_spd_avg` decimal(15,3) DEFAULT NULL,
`year` decimal(15,3) DEFAULT NULL,
`month` decimal(15,3) DEFAULT NULL,
`month_year` decimal(15,3) DEFAULT NULL,
`date_cns` datetime DEFAULT NULL,
UNIQUE KEY `dvc` (`dvc`,`date_str`,`pg_avg`) USING BTREE,
UNIQUE KEY `uidx_dvc_date_cns` (`dvc`,`date_cns`),
KEY `month` (`month`),
KEY `year` (`year`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+--------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.01 sec)
The workaround I had done was to create a duplicate table without indexes. I have executed the same SQL for partition creation did work (ALTER TABLE cns_dvc PARTITION BY etc.).
All columns defined in unique indexes of the table should be part of partition definition which means those 4 columns in this case: dvc, date_str, pg_avg, date_cns
I guess it will be easier for me to create again the table with partition. Then adding uniques indexes on the partition.
You have UNIQUE keys, but each has at least one NULLable column. So none can be promoted to PRIMARY KEY.
Every table should have a PK. In your case, an hidden (inaccessible) PK will be generated for you.
Why have two UNIQUE keys? That is often a schema design error.
Don't partition a table unless it has at least a million rows.
Don't expect performance improvement by simply partitioning.
Do use partitioning if you need to delete "old" data; is that what you are doing?
"A UNIQUE INDEX must include all columns in the table's partitioning function" is an absolute requirement. (Maybe some year there will be "global" unique keys.)
You have "month" in several columns, of multiple datatypes; please explain. Normally, it is best to clean up dates/datetimes during input, and use DATE, DATETIME, and/or TIMESTAMP, not VARCHAR. And I have never heard of using DECIMAL!?
It is usually better to pick apart a DATE in a SELECT than to have the parts spread across column.
Let's see the main SELECTs; we can advise on how to provide optimal indexing for a partitioned and a non-partitioned table.

mysql won´t create me an foreign key, cause no index in referenced table (but index exist!)

Moin moin (like we in Hamburg say),
i wanted to add a column with a foreign key in a existing table with filled records. and referencing the key to another table with primary key. so far so good.
But i can´t cause mysql says me that the index for the referenced table is not existing. But it actually does. so i don´t know, what´s the point is.
the error:
2017-04-11 19:21:08 0x1770 Error in foreign key constraint of table animals/#sql
-7a0_7:
foreign key(pet_id) references pet (pet_id):
Cannot find an index in the referenced table where the
referenced columns appear as the first columns, or column types
in the table and the referenced table do not match for constraint.
the referenced table:
+---------+-----------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------+-----------------+------+-----+---------+----------------+
| pet_id | int(3) unsigned | NO | PRI | NULL | auto_increment |
| name | varchar(20) | YES | | NULL | |
| owner | varchar(20) | YES | | NULL | |
| species | varchar(10) | YES | | NULL | |
| sex | char(1) | YES | | NULL | |
| birth | date | YES | | NULL | |
| death | date | YES | | NULL | |
+---------+-----------------+------+-----+---------+----------------+
7 rows in set (0.00 sec)
and the index:
+-------+------------+----------+--------------+-------------+-----------+------
-------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardi
nality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+----------+--------------+-------------+-----------+------
-------+----------+--------+------+------------+---------+---------------+
| pet | 0 | PRIMARY | 1 | pet_id | A |
9 | NULL | NULL | | BTREE | | |
| pet | 1 | pet_id | 1 | pet_id | A |
9 | NULL | NULL | | BTREE | | |
| pet | 1 | pet_id | 2 | name | A |
9 | NULL | NULL | YES | BTREE | | |
| pet | 1 | pet_id | 3 | owner | A |
9 | NULL | NULL | YES | BTREE | | |
| pet | 1 | pet_id | 4 | species | A |
9 | NULL | NULL | YES | BTREE | | |
| pet | 1 | pet_id | 5 | sex | A |
9 | NULL | NULL | YES | BTREE | | |
| pet | 1 | pet_id | 6 | birth | A |
9 | NULL | NULL | YES | BTREE | | |
| pet | 1 | pet_id | 7 | death | A |
9 | NULL | NULL | YES | BTREE | | |
+-------+------------+----------+--------------+-------------+-----------+------
-------+----------+--------+------+------------+---------+---------------+
8 rows in set (0.10 sec)
if it helps............
UPDATE: result of SHOW CREATE TABLE pet:
| pet | CREATE TABLE `pet` (
`pet_id` int(3) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(20) DEFAULT NULL,
`owner` varchar(20) DEFAULT NULL,
`species` varchar(10) DEFAULT NULL,
`sex` char(1) DEFAULT NULL,
`birth` date DEFAULT NULL,
`death` date DEFAULT NULL,
PRIMARY KEY (`pet_id`),
KEY `pet_id` (`pet_id`,`name`,`owner`,`species`,`sex`,`birth`,`death`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8 |

DEFAULT NULL column when column created with NOT NULL

I created a table in mysql. Every column in my table I created with NOT NULL. What does the NULL value in my DEFAULT column mean? I never plan to have a NULL value in those columns.
+------------+--------------+------+-----+-------------------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+-------------------+-------+
| user_id | binary(16) | NO | PRI | | |
| first_name | varchar(255) | NO | | NULL | |
| last_name | varchar(255) | NO | | NULL | |
| email | varchar(255) | NO | UNI | NULL | |
| digest | binary(40) | NO | | NULL | |
| join_ts | timestamp | NO | | CURRENT_TIMESTAMP | |
+------------+--------------+------+-----+-------------------+-------+
This means you don't have a default value for these columns.
If you have a default value, you can create an insert query without that column.
With your table, you must give a value to all the null default's columns

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

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.