Issue with Collation in Mysql - mysql

I have a table as
mysql> show create table tbl_name\G
************* 1. row *************
Table: tbl_name
Create Table: CREATE TABLE `tbl_name` (
`name` char(15) CHARACTER SET latin1 DEFAULT NULL,
`id` int(5) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=5 DEFAULT CHARSET=latin7 COLLATE=latin7_estonian_cs
1 row in set (0.00 sec)
The DATA In Table is as
mysql> select * from tbl_name;
name id
manaf 1
manaf 2
MANAF 3
MAnaf 4
4 rows in set (0.00 sec)
Now i want the Case Sensitivity in all the records
mysql> select distinct(name) from tbl_name;
It should return the 3 rows in result but it is returing just 1.why..??
As I have set the table collation as latin7_estonian_cs

try this
SELECT DISTINCT BINARY value FROM tableName
Reference

Related

MariaDB AUTO_INCREMENT Jump to Max (unsigned) int

EDIT: it was a bug in or application
What could cause the auto_increment value to jump up billions of values to strike max int?
Our core table uses an int unsigned auto_increment primary key column. Today it skipped every value all the way up to 4294967295.
I was able to resolve this by deleting the offensive row and running
ALTER TABLE [table] AUTO_INCREMENT = [new value];
but I cannot explain how or why it happened.
Our environment is MariaDB 10.2.27 under PHP/Apache.
Any INSERT can specify a high value, and this will implicitly advance the next auto-increment value. In other words, an auto-increment for a table will never be less than the largest value currently inserted in the table, and any client can override the auto-increment mechanism simply by specifying a value in an INSERT.
Demo:
mysql> create table mytable (id int unsigned auto_increment primary key);
mysql> insert into mytable (id) values (DEFAULT);
Query OK, 1 row affected (0.01 sec)
That should have inserted id value 1, so the next AI will be 2:
mysql> show create table mytable\G
*************************** 1. row ***************************
Table: mytable
Create Table: CREATE TABLE `mytable` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4
Now I specify a large value, and the AI is updated accordingly:
mysql> insert into mytable (id) values(1000000000);
Query OK, 1 row affected (0.01 sec)
mysql> show create table mytable\G
*************************** 1. row ***************************
Table: mytable
Create Table: CREATE TABLE `mytable` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1000000001 DEFAULT CHARSET=utf8mb4
Note a value greater than the max unsigned int value 232-1 will be truncated to that value.
mysql> insert into mytable (id) values(1000000000000);
Query OK, 1 row affected, 1 warning (0.00 sec)
mysql> show create table mytable\G
*************************** 1. row ***************************
Table: mytable
Create Table: CREATE TABLE `mytable` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4294967295 DEFAULT CHARSET=utf8mb4
So someone must have inserted a large value. Any value larger than 4294967295 will be truncated to 4294967295, and then subsequent inserts that try to use the AI sequence will fail.

MySQL 'NOT NULL' Error

I have question about 'NOT NULL' error. I need to make a table with variable type: 'SERIAL' and length of 7. Here is an error that SQL sends to me:
SQL query:
CREATE TABLE `table42`.`CheckOuts ` (
`CheckOutID` SERIAL( 7 ) NOT NULL
) ENGINE = MYISAM ;
The error that is returned:
#1064 - You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use
near '(7) NOT NULL) ENGINE = MyISAM' at line 1
I think your problem is that SERIAL isn't supported in that method for MySQL. Docs suggest you should be using AUTO_INCREMENT instead:
see: http://www.sqlines.com/mysql/auto_increment
also: What is the difference between SERIAL and AUTO_INCREMENT in mysql
These suggest you should be creating your table with the following example syntax:
create table myfriends (
id int primary key auto_increment,
frnd_name varchar(50) not null
);
The SERIAL type already has NOT NULL as part of its definition, so your NOT NULL declaration is redundant
Error is not due to NOT NULL, although SERIAL already includes NOT NULL, an error does not occur when duplicating it. The cause of the error is for the length that you try to assign (7):
mysql> DROP TABLE IF EXISTS `CheckOuts`;
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE TABLE IF NOT EXISTS `CheckOuts` (
-> -- `CheckOutID` SERIAL(7) NOT NULL
-> `CheckOutID` SERIAL NOT NULL
-> ) ENGINE=MYISAM;
Query OK, 0 rows affected (0.00 sec)
mysql> SHOW CREATE TABLE `CheckOuts`\G
*************************** 1. row ***************************
Table: CheckOuts
Create Table: CREATE TABLE `CheckOuts` (
`CheckOutID` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
UNIQUE KEY `CheckOutID` (`CheckOutID`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
1 row in set (0.00 sec)
I don't understand what you're trying to do, but if you need to assign a length, you'll need something like:
mysql> DROP TABLE IF EXISTS `CheckOuts`;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> CREATE TABLE IF NOT EXISTS `CheckOuts` (
-> `CheckOutID` INT(7) UNSIGNED SERIAL DEFAULT VALUE
-> ) ENGINE=MYISAM;
Query OK, 0 rows affected (0.00 sec)
mysql> SHOW CREATE TABLE `CheckOuts`\G
*************************** 1. row ***************************
Table: CheckOuts
Create Table: CREATE TABLE `CheckOuts` (
`CheckOutID` int(7) unsigned NOT NULL AUTO_INCREMENT,
UNIQUE KEY `CheckOutID` (`CheckOutID`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
1 row in set (0.00 sec)
See documentation:
11.1.1 Numeric Type Overview
...
SERIAL is an alias for BIGINT UNSIGNED NOT NULL AUTO_INCREMENT
UNIQUE.
SERIAL DEFAULT VALUE in the definition of an integer column is an
alias for NOT NULL AUTO_INCREMENT UNIQUE.
...

Set AUTO_INCREMENT on a column with missing values

I have a table called users in my database. It has a field id of type int. As of now this is manually incremented for every user that registers and some intermediate values are missing because of deleted user accounts. I cannot change the user id of other registered users . I tried to change this column to AUTO_INCREMENT using this statement
ALTER TABLE `userinfo` CHANGE `id` `id` BIGINT(20) NOT NULL AUTO_INCREMENT;
But I got the following error
1062 - ALTER TABLE causes auto_increment resequencing, resulting in
duplicate entry '1' for key 'PRIMARY'
I only have around 200 users in my table. So I wanted to start AUTO_INCREMENT from 201. I executed the following statements
ALTER TABLE `userinfo` AUTO_INCREMENT=201;
ALTER TABLE `userinfo` CHANGE `id` `id` INT(10) NOT NULL AUTO_INCREMENT;
But still I encounter the same issue.
If you don't have duplicates (id), you should not have problems:
mysql> SELECT VERSION();
+-----------+
| VERSION() |
+-----------+
| 5.7.17 |
+-----------+
1 row in set (0.00 sec)
mysql> DROP TABLE IF EXISTS `userinfo`;
Query OK, 0 rows affected (0.01 sec)
mysql> CREATE TABLE IF NOT EXISTS `userinfo` (
-> `id` INT(11) NOT NULL
-> );
Query OK, 0 rows affected (0.00 sec)
mysql> INSERT INTO `userinfo`
-> (`id`)
-> VALUES
-> (1),
-> (2),
-> (3),
-> -- (1),
-> (10),
-> (11),
-> (15),
-> (20),
-> (182),
-> (191);
Query OK, 9 rows affected (0.00 sec)
Records: 9 Duplicates: 0 Warnings: 0
mysql> ALTER TABLE `userinfo`
-> CHANGE `id` `id` BIGINT(20) NOT NULL
-> PRIMARY KEY AUTO_INCREMENT;
Query OK, 9 rows affected (0.00 sec)
Records: 9 Duplicates: 0 Warnings: 0
mysql> ALTER TABLE `userinfo` AUTO_INCREMENT = 201;
Query OK, 0 rows affected (0.00 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> SHOW CREATE TABLE `userinfo`\G
*************************** 1. row ***************************
Table: userinfo
Create Table: CREATE TABLE `userinfo` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=201 DEFAULT CHARSET=utf8mb4
1 row in set (0.00 sec)
In another case:
mysql> SELECT VERSION();
+-----------+
| VERSION() |
+-----------+
| 5.7.17 |
+-----------+
1 row in set (0.00 sec)
mysql> DROP TABLE IF EXISTS `userinfo`;
Query OK, 0 rows affected (0.01 sec)
mysql> CREATE TABLE IF NOT EXISTS `userinfo` (
-> `id` INT(11) NOT NULL
-> );
Query OK, 0 rows affected (0.00 sec)
mysql> INSERT INTO `userinfo`
-> (`id`)
-> VALUES
-> (1),
-> (2),
-> (3),
-> (1), -- Duplicate
-> (10),
-> (11),
-> (15),
-> (20),
-> (182),
-> (191);
Query OK, 10 rows affected (0.00 sec)
Records: 10 Duplicates: 0 Warnings: 0
mysql> ALTER TABLE `userinfo`
-> CHANGE `id` `id` BIGINT(20) NOT NULL
-> PRIMARY KEY AUTO_INCREMENT;
ERROR 1062 (23000): ALTER TABLE causes auto_increment resequencing, resulting in duplicate entry '1' for key 'PRIMARY'
Try resetting the column to primary key, like this:
ALTER TABLE `userinfo` CHANGE `id` `id` INT(10) PRIMARY KEY AUTO_INCREMENT;
You can just drop auto_increment then set auto_increment, do not need recreate primary key
ALTER TABLE `userinfo` CHANGE `id` `id` int NOT NULL;
ALTER TABLE `userinfo` AUTO_INCREMENT=9;
ALTER TABLE `userinfo` CHANGE `id` `id` int NOT NULL AUTO_INCREMENT;
I was having this same problem/error (MySql 5.7.28) with bulk inserts of data that was missing primary key/auto_increment values - even though there were no duplicates. I wanted to preserve the primary key and needed to preserve the original field values also as resequencing would have caused data-integrity problems in the system.
My solution was to remove the auto_increment and then primary key as suggested above:
ALTER TABLE `userinfo` CHANGE `id` `id` int NOT NULL;
ALTER TABLE `userinfo` DROP PRIMARY KEY;
Then run my bulk insert statement without resequencing problems.
Then restore the primary key and original values using the following steps:
renaming the original PK/auto-increment field which now has the desired values in it
creating a new PK/auto-increment field with the original field name
setting the auto-increment value to one more than the max value of the renamed field
copying the original values into the new PK/auto-increment field
dropping the renamed field (now you have the original schema with PK/auto-increment field with original gaps in the sequence as desired.
Here is the sql for the first two steps:
ALTER TABLE `userinfo` CHANGE `id` `orig_id` INT;
ALTER TAble `userinfo` add id int auto_increment not null primary key;
Then use the following query result:
select max(orig_id) + 1 from `userinfo`;
to set the new auto-increment, before updating the new PK/auto-increment values:
ALTER TABLE `userinfo` AUTO_INCREMENT=201;
UPDATE `userinfo` set id = orig_id;
ALTER TABLE `userinfo` drop column orig_id;
and now I've got the original table values copied exactly as wanted. I hope this helps others save time.

change character encoding of mysql table

When I change the character set of a table from utf8 to latin1, the columns still keep the old setting.
For e.g. in the example below, name column is still utf8 even if the table is converted to latin1
mysql> create table mytest (id int, name varchar(255)) engine=myisam default charset=utf8;
Query OK, 0 rows affected (0.02 sec)
mysql> alter table mytest charset=latin1;
Query OK, 0 rows affected (0.02 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> show create table mytest\G
*************************** 1. row ***************************
Table: mytest
Create Table: CREATE TABLE `mytest` (
`id` int(11) DEFAULT NULL,
`name` varchar(255) CHARACTER SET utf8 DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
1 row in set (0.00 sec)
This must be to preseve the data integrity. But is there any way to change everything to latin1. I am not much worried about data. I am ok if there are a few junk characters due to conversion.

Importance of Default charset

I have a 4 GB table and the default charset was set to utf8 though I am saving only latin1 characters.
I changed it to latin1 using alter table statement on a test machine.
The index file log_details.MYI was reduced by 5% while there was no difference noted in the data file, log_details.MYD
I have a few questions:
1) Should I alter the table on production? is it worth it?
2) Will it improve the select speed?
3) I guess I can have longer indexes once I change the default charset to latin1. Any
other advantage?
I have also noted that after changing the default charset using alter table statement, the varchar columns types were changed automatically.
Item_ID varchar(32) character set utf8 How do I avoid this?
mysql> create table char_test( id int, Item_ID varchar(32) ) default charset = utf8;
Query OK, 0 rows affected (0.02 sec)
mysql> insert into char_test values (1, 'abc');
Query OK, 1 row affected (0.00 sec)
mysql> show create table char_test\G
*************************** 1. row ***************************
Table: char_test
Create Table: CREATE TABLE `char_test` (
`id` int(11) default NULL,
`Item_ID` varchar(32) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
mysql> alter table char_test default charset = latin1;
Query OK, 1 row affected (0.03 sec)
Records: 1 Duplicates: 0 Warnings: 0
mysql> show create table char_test\G
*************************** 1. row ***************************
Table: char_test
Create Table: CREATE TABLE `char_test` (
`id` int(11) default NULL,
`Item_ID` varchar(32) character set utf8 default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
1 row in set (0.00 sec)
Performance is probably the last thing you should care about. What character set is you client-side app using? What natural language is the info written on? Those are the questions you must make.
If you stick to Latin1 you won't be able to store Japanese characters but also some common chars like the € symbol. On the other side, using UTF-8 in the database may be useless (or plain wrong) if your application cannot handle multi-byte input.