MySQL collation case INSENSITIVE search for utf8mb4_bin [duplicate] - mysql

I found out that when I query one of my tables it is case sensitive, so I tried to change the collation (I'm using Workbench in windows). I
right clicked on the table -> alter table -> collation
-> changed from utf8mb4_default to utf8mb4_general_ci
But it didn't work and the queries are still case sensitive. and when I
right click on the table -> alter table -> collation
is utf8mb4_default
and when I change it to utf8mb4_general_ci again, and apply the change, it says no changes detected!
The column type is VARBINARY, I tried this:
MySQL case insensitive search on varbinary field?
but it takes a lot of time, it is not acceptable.
This is t create statement:
CREATE TABLE `page` (
`page_id` int(8) unsigned NOT NULL AUTO_INCREMENT,
`page_namespace` int(11) NOT NULL DEFAULT '0',
`page_title` varbinary(255) NOT NULL DEFAULT '',
`page_restrictions` tinyblob NOT NULL,
`page_counter` bigint(20) unsigned NOT NULL DEFAULT '0',
`page_is_redirect` tinyint(1) unsigned NOT NULL DEFAULT '0',
`page_is_new` tinyint(1) unsigned NOT NULL DEFAULT '0',
`page_random` double unsigned NOT NULL DEFAULT '0',
`page_touched` varbinary(14) NOT NULL DEFAULT '',
`page_links_updated` varbinary(14) DEFAULT NULL,
`page_latest` int(8) unsigned NOT NULL DEFAULT '0',
`page_len` int(8) unsigned NOT NULL DEFAULT '0',
`page_content_model` varbinary(32) DEFAULT NULL,
PRIMARY KEY (`page_id`),
UNIQUE KEY `name_title` (`page_namespace`,`page_title`),
KEY `page_random` (`page_random`),
KEY `page_len` (`page_len`),
KEY `page_redirect_namespace_len` (`page_is_redirect`,`page_namespace`,`page_len`),
KEY `idx_page_page_is_new` (`page_is_new`),
KEY `idx_page_page_title_is_new` (`page_title`,`page_is_new`)
) ENGINE=InnoDB AUTO_INCREMENT=44062999 DEFAULT CHARSET=utf8mb4;
Any other suggestions?

Looks like you have the following options:
Convert your binary column to a none binary text column, using a temp column because binary columns cannot be case in-sensitive
Use the Convert function as the link you mentioned
Use the Lower or Upper methods
If you really want the column be always case in-sensitive, I'd say go for option 1.

In mysql there is a collation for each column in addition to the overall collation of the table. You will need to change the collation for each individual column.
(I believe the overall table collation determines the default collation if you create a new column, but don't quote me on that.)

Related

MySQL Default Value as Expression is Wrong

I am running MySQL 8.0.17 and trying to add a default value to a column definition, specifically a JSON column.
create table `test` (`id` bigint unsigned not null auto_increment primary key, `name` varchar(255) not null, `notes` json default ('[]')) default character set utf8mb4 collate 'utf8mb4_unicode_ci'
The query executes fine, but when I look at the table structure the default value is listed as "(_utf8mb4'[]')".
This even happens if I set a default value for a VARCHAR field, but enclose the string in parentheses.
I've also tried using the MySQL JSON_ARRAY() function.
create table `test` (`id` bigint unsigned not null auto_increment primary key, `name` varchar(255) not null, `notes` json default (JSON_ARRAY())) default character set utf8mb4 collate 'utf8mb4_unicode_ci'
but this puts the "(json_array())" as a string as the default.
I feel like I'm doing this write based on the documentation. Is this a bug? or am I missing something?
Thanks!

MySQL alter table gives unknown column error

I'm renaming a bunch of columns in a lot of my tables and changing their data types for a major system update, and I haven't had many issues except for this one.
Error Code: 1054. Unknown column 'FactoryID' in 'factories'
show create table `factories`;
CREATE TABLE `factories` (
`FactoryID` char(36) COLLATE utf8mb4_unicode_ci NOT NULL,
`ParentFactoryID` char(36) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`Name` varchar(256) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`Notes` varchar(1024) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`DateTimeAdded` datetime DEFAULT NULL,
`CountryID` smallint(5) unsigned NOT NULL,
`ListID` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`Deleted` int(1) DEFAULT '0',
PRIMARY KEY (`FactoryID`),
UNIQUE KEY `FactoryID` (`FactoryID`),
KEY `ParentFactoryID` (`ParentFactoryID`),
KEY `CountryID` (`CountryID`),
CONSTRAINT `factories[CountryID]` FOREIGN KEY (`CountryID`) REFERENCES `countries` (`CountryID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
ALTER TABLE `sterling`.`factories`
CHANGE COLUMN `CountryID` `CountryID` SMALLINT(5) UNSIGNED NOT NULL AFTER `FactoryID`,
CHANGE COLUMN `ParentFactoryID` `_OriginalFactoryID` CHAR(36) CHARACTER SET 'utf8mb4' COLLATE 'utf8mb4_unicode_ci' NULL DEFAULT NULL AFTER `ListID`,
CHANGE COLUMN `DateTimeAdded` `__Added` TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) AFTER `__Active`,
CHANGE COLUMN `Deleted` `__Active` TINYINT(1) NOT NULL DEFAULT 1 ,
ADD COLUMN `__Updated` TIMESTAMP(6) NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP(6) AFTER `__Added`,
drop primary key,
change column`FactoryID` `#FactoryID`char(36)null after`__Updated`,
add column`FactoryID`binary(8)not null first,
add index`#FactoryID`(`#FactoryID`);
Am I missing an order of operations sort of thing? If all of those changes happen in order, I'm not sure what exactly the problem is, since at no time that FactoryID is referenced does it not exist.
The columnname that after refers to is supposed to be the new name of the column in the final table. It doesn't matter where in the statement you change the name.
And it actually even makes this following statement fail:
alter table tablename
add column b int after a,
drop column a
Error Code: 1054. Unknown column 'a' in 'tablename'
as in the final table, there will be no column a anymore, so it is invalid even if you drop a only after you already added column b.
In your case, you would need to change
CHANGE COLUMN `CountryID` `CountryID` ... AFTER `FactoryID`,
to
CHANGE COLUMN `CountryID` `CountryID` ... AFTER `#FactoryID`,
in order to anticipate that you will (later) rename the column FactoryID to #FactoryID.
To make it complete: in after, you cannot refer to a column that you will add later. For example, in the end of your statement, you actually add another column FactoryID, but you cannot yet refer to it here (otherwise, the query would not have failed). You could add that column first though (and even before you rename the original FactoryId, MySQL allows you to swap columnnames that way). CHANGE COLUMN CountryID CountryID ... AFTER FactoryID would then work, but would refer to the new column (so in total, CountryID would be the 2nd column, which may or may not be what you intended).
I don't know if it is officially documented somewhere, you will probably have to take it as convention, but it has "always" been that way.

How can i define a column as tinyint(4) using sequelize ORM

I need to define my table as
CREATE TABLE `test` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`o_id` int(11) unsigned NOT NULL,
`m_name` varchar(45) NOT NULL,
`o_name` varchar(45) NOT NULL,
`customer_id` int(11) unsigned NOT NULL,
`client_id` tinyint(4) unsigned DEFAULT '1',
`set_id` tinyint(4) unsigned DEFAULT NULL,
`s1` tinyint(4) unsigned DEFAULT NULL,
`s2` tinyint(4) unsigned DEFAULT NULL,
`s3` tinyint(4) unsigned DEFAULT NULL,
`review` varchar(2045) DEFAULT NULL,
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `br_o_id_idx` (`order_id`),
KEY `br_date_idx` (`created_at`),
KEY `br_on_idx` (`operator_name`),
KEY `br_mn_idx` (`merchant_name`)
)
but as i am looking on sequelize documentation , it does not have support for tiny int with its size.
From the lack of ZERO_FILL in your table definition, I suspect tinyint(4) probably does not do what you think it does. From 11.2.5 Numeric Type Attributes:
MySQL supports an extension for optionally specifying the display width of integer data types in parentheses following the base keyword for the type.
...
The display width does not constrain the range of values that can be stored in the column.
...
For example, a column specified as SMALLINT(3) has the usual SMALLINT range of -32768 to 32767, and values outside the range permitted by three digits are displayed in full using more than three digits.
I'm not sure if other RDBMSs treat the number in parens differently, but from perusing the sequelize source it looks like they're under the same, incorrect, impression you are.
That being said, the important part of your schema, being that you want to store those fields as TINYINTs (using only a byte of storage to contain values between 0-255), is sadly not available in the Sequelize DataTypes. I might suggest opening a PR to add it...
On the other hand, if you really are looking for the ZEROFILL functionality, and need to specify that display width of 4, you could do something like Sequelize.INTEGER(4).ZEROFILL, but obviously, that would be pretty wasteful of space in your DB.
For MySQL, the Sequelize.BOOLEAN data type maps to TINYINT(1). See
https://github.com/sequelize/sequelize/blob/3e5b8772ef75169685fc96024366bca9958fee63/lib/data-types.js#L397
and
http://docs.sequelizejs.com/en/v3/api/datatypes/
As noted by #user866762, the number in parentheses only affects how the data is displayed, not how it is stored. So, TINYINT(1) vs. TINYINT(4) should have no effect on your data.

MySQL Community 5.7 - Invalid default value (datetime field type)

I've just installed MySQL Community Server 5.7 and I am trying to create the following table:
CREATE TABLE IF NOT EXISTS `atcommandlog` (
`atcommand_id` mediumint(9) unsigned NOT NULL auto_increment,
`atcommand_date` datetime NOT NULL default '0000-00-00 00:00:00',
`account_id` int(11) unsigned NOT NULL default '0',
`char_id` int(11) unsigned NOT NULL default '0',
`char_name` varchar(25) NOT NULL default '',
`map` varchar(11) NOT NULL default '',
`command` varchar(255) NOT NULL default '',
PRIMARY KEY (`atcommand_id`),
INDEX (`account_id`),
INDEX (`char_id`)
) ENGINE=MyISAM AUTO_INCREMENT=1;
This gives me the following error:
#1067 - Invalid default value for 'atcommand_date'
This same query works fine on MySQL 5.6. Has the default datetime value been changed in MySQL 5.7?
This looks like more of a SQL mode issue than the char set. Strict
mode (and more specifically NO_ZERO_DATE which is part of strict mode)
usually sets off that error if the table was created with an all zero
default date before turning on strict.
What we use (for similar modified date columns), is the '1970-01-01
00:00:01'.
and on a slightly related note, we use timestamp for these columns
(and for created time too). Takes half the storage space, and is
faster access.
https://dba.stackexchange.com/questions/6171/invalid-default-value-for-datetime-when-changing-to-utf8-general-ci

Drupal encoding and node insert

I have a CCK type for storing mentions (Social Media search mentions). Some of the mentions I believe are ASCII (My knowledge of this stuff is little).
I retrieve data from API's, which I then using node_save to save to Drupal.
My question is, what should I use to safely convert whatever I am getting into a format Drupal and MySQL are happy with?
The particular db_query error I get is unhelpfull "Warning in test1\includes\common.inc on line 3538". Nice. I have traced it to be encoding, as I used the following code to make the input safe, but it is not working with all input.
$node->title = htmlentities($item['title'], ENT_COMPAT, 'UTF-8');
It worked well for some ASCII characters, like those square ones [] etc, but not for this "行けなくてもずっとユーミンは聴きつづけます".
I'm really stuck. :(
UPDATE: The EXACT error I get from PHP is "Warning in D:\sites\test1\includes\common.inc on line 3538", and the line reads "if (db_query($query, $values)) {".
UPDATE 2: I've confirmed that the encoding of the data I am receiving is UTF8. This really doesn't make sense now, and I've confirmed that the collation in the db is utf8_general_ci.
UPDATE 3: One of the title's is: How Much Does A Facebook Fan Cost?� $1.07
The output of:
var_export(array_map('ord', str_split($node->title))
gave me the character 160 for the funny question mark (which is a square like [] in eclipse).
UPDATE 4: MySQL version is 5.1.41, and the collation on the columns is utf8_general_ci.
UPDATE 5: I managed to get Drupal to print the query with db_queryd. Funny thing is now I get the exact error message and not "Warning in", but Drupal still doesn't have this error in the log! WTF. So the exact sql is:
INSERT INTO node (vid, type, language, title, uid, status, created, changed, comment, promote, moderate, sticky, tnid, translate) VALUES (0, 'sm_mention', '', 'How Much Does A Facebook Fan Cost?� $1.07 (Geoffrey A. Fowler/Digits)', 1, 1, 1298395302, 1298395302, 0, 0, 0, 0, 0, 0)
And the error given is: Incorrect string value: '\xA0 $1.0...' for column 'title' at row 1
This honestly sounds like something doesn't like extended ascii characters.
UPDATE 6:
SHOW CREATE TABLE node:
CREATE TABLE `node` (
`nid` int(10) unsigned NOT NULL AUTO_INCREMENT,
`vid` int(10) unsigned NOT NULL DEFAULT '0',
`type` varchar(32) NOT NULL DEFAULT '',
`language` varchar(12) NOT NULL DEFAULT '',
`title` varchar(255) NOT NULL DEFAULT '',
`uid` int(11) NOT NULL DEFAULT '0',
`status` int(11) NOT NULL DEFAULT '1',
`created` int(11) NOT NULL DEFAULT '0',
`changed` int(11) NOT NULL DEFAULT '0',
`comment` int(11) NOT NULL DEFAULT '0',
`promote` int(11) NOT NULL DEFAULT '0',
`moderate` int(11) NOT NULL DEFAULT '0',
`sticky` int(11) NOT NULL DEFAULT '0',
`tnid` int(10) unsigned NOT NULL DEFAULT '0',
`translate` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`nid`),
UNIQUE KEY `vid` (`vid`),
KEY `node_changed` (`changed`),
KEY `node_created` (`created`),
KEY `node_moderate` (`moderate`),
KEY `node_promote_status` (`promote`,`status`),
KEY `node_status_type` (`status`,`type`,`nid`),
KEY `node_title_type` (`title`,`type`(4)),
KEY `node_type` (`type`(4)),
KEY `uid` (`uid`),
KEY `tnid` (`tnid`),
KEY `translate` (`translate`)
) ENGINE=InnoDB AUTO_INCREMENT=1700 DEFAULT CHARSET=utf8
\xA0 is not a valid start of a UTF8 sequence.
The character known as NO-BREAK SPACE having the Unicode codepoint 0x00A0 should be encoded as 0xC2A0 in UTF8.
Thus said, your input string is broken, it's not a valid UTF8.