Unique keys > 3072 bytes allowed in MariaDB versions > 10.5 - indexing

I discovered the normal 3072 byte key limitation in MariaDB 10.3 while running this statement:
ALTER TABLE table1 ADD UNIQUE INDEX idx_my_composite_uniqueai_usr_email_uniq (table2_uuid ASC, table3_uuid ASC, text_column ASC)
Which gave the expected error:
ERROR 1071 (42000) at line 31: Specified key was too long; max key length is 3072 bytes
DDL for table1:
CREATE TABLE table1
(
uuid char(36) CHARACTER SET ascii NOT NULL,
table2_fk_uuid char(36) CHARACTER SET ascii NOT NULL,
table3_fk_uuid char(36) CHARACTER SET ascii NOT NULL,
text_field varchar(1024) DEFAULT NULL,
PRIMARY KEY (uuid),
KEY fk_table2_fk_uuid (table2_fk_uuid),
KEY fk_table3_fk_uuid (table3_fk_uuid),
CONSTRAINT fk_table1_table2 FOREIGN KEY (table2_uuid) REFERENCES table2 (uuid) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT fk_table1_table3 FOREIGN KEY (table3_uuid) REFERENCES table3 (uuid) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
My understanding is that the total key length for this unique key is 1024 * 4 (because text_field column is CHARSET=utfmb3) + 36 * 2 = 4168 bytes.
I realize that shortening the text_field column width if possible is the best way to stay within the key length limitation. However, prior to understanding this I upgraded my MariaDB server to 10.5 and also to 10.6 and the ALTER TABLE command executes just fine and the key is created.
Has the key limitation been expanded in the later db version? I'm not see that it did in the MariaDB documentation. If not, what else am I missing?

The limitation was removed back in 10.4. Release notes mention it :
"Unique indexes can be created on BLOB or TEXT fields (MDEV-371)"

Related

Is it possible to use Text for SQL Indexing

I got the following error:
PDOException: SQLSTATE[42000]: Syntax error or access violation: 1170 BLOB/TEXT column 'summary' used in key specification without a key length in c:\website\someclass.php
Is it possible to use TEXT for SQL Indexing?
Here's my code:
CREATE TABLE conversation (
conversation_id INT(7) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
some_id INT(7) UNSIGNED,
summary TEXT,
INDEX(conversation_id, some_id, summary)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
No, it is not possible to use the TEXT data type for indexing, as the error message suggests.
The reason for this is that the TEXT data type can potentially store a large amount of data, and therefore cannot be indexed efficiently. The error message specifically refers to the fact that the summary column is being used in the index without specifying a length for the index key, which is not allowed for BLOB and TEXT columns.
To fix this error, you can modify your conversation table to use a different data type for the summary column that can be indexed, such as VARCHAR or CHAR:
CREATE TABLE conversation (
conversation_id INT(7) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
some_id INT(7) UNSIGNED,
summary VARCHAR(255),
INDEX(conversation_id, some_id, summary(255))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CHECK with ^[A-Z]{3}[0-9]{6}$ - SQL Server

CREATE TABLE PARTICIPANTE(
pasaporte NVARCHAR(9) NOT NULL,
nombre NVARCHAR(50) NOT NULL,
sexo CHAR(1) NOT NULL,
fecNac DATE NOT NULL,
codPais NVARCHAR(3) NOT NULL,
CONSTRAINT PK_PARTICIPANTE PRIMARY KEY (pasaporte),
CONSTRAINT FK_PAIS_PARTICIPANTE FOREIGN KEY (codPais) REFERENCES PAIS(codigo),
CONSTRAINT CHK_PASAPORTE CHECK (pasaporte like '^\[A-Z\]{3}\[0-9\]{6}$')
)
The CONSTRAINT CHK_PASAPORTE doesn't work when I try to insert the data.
The INSERT statement conflicted with the CHECK constraint "CHK_PASAPORTE". The conflict occurred in database "OMA", table "dbo.PARTICIPANTE", column 'pasaporte'.
Example
insert into PARTICIPANTE (pasaporte,nombre,sexo,fecNac,codPais) value ('JPN865653','Noguchi','F','20000104','JPN');
Can someone explain to me why this doesn't work and how can I fix it?
As I mention in the comments, SQL Server has no (in built) support for Regex, it only has basic pattern matching, which is explained in the documentation.
Fortunately, the logic you are after appears to be quite simple; 3 letters followed by 6 digits. This can be achieved with the following constraint:
ALTER TABLE dbo.PARTICIPANTE ADD CONSTRAINT CHK_PASAPORTE CHECK (pasaporte LIKE '[A-Z][A-Z][A-Z][0-9][0-9][0-9][0-9][0-9][0-9]');
Note that if you require the value to only contain uppercase values, you'll need to COLLATE the value to a collation that is case sensitive and orders upper case letters first, then lowercase, and finally alphabetically (Binary collations are one such one that does this).

#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server

I was trying to run following Query on my sql server :
CREATE TABLE `e_store`.`products`(
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT ,
`name` VARCHAR(250) NOT NULL ,
`brand_id` INT UNSIGNED NOT NULL ,
`category_id` INT UNSIGNED NOT NULL ,
`attributes` JSON NOT NULL ,
PRIMARY KEY(`id`) ,
INDEX `CATEGORY_ID`(`category_id` ASC) ,
INDEX `BRAND_ID`(`brand_id` ASC) ,
CONSTRAINT `brand_id` FOREIGN KEY(`brand_id`) REFERENCES `e_store`.`brands`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE ,
CONSTRAINT `category_id` FOREIGN KEY(`category_id`) REFERENCES `e_store`.`categories`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE
);
I have already brands and categories tables on my e_store database.
But I got the following Error :
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'JSON NOT NULL ,
PRIMARY KEY(`id`) ,
INDEX `CATEGORY_ID`('category_id' ' at line 6
For those who are facing this issue similar to me:
MariaDB does not natively implement the JSON data type but it uses it as an alias for LONGTEXT for compatibility reasons. According to the documentation (https://mariadb.com/kb/en/library/json-data-type/):
JSON is an alias for LONGTEXT introduced for compatibility reasons with MySQL's JSON data type. MariaDB implements this as a LONGTEXT rather, as the JSON data type contradicts the SQL standard, and MariaDB's benchmarks indicate that performance is at least equivalent.
In order to ensure that a a valid json document is inserted, the JSON_VALID function can be used as a CHECK constraint.
So if you are having issues with the JSON data type in MariaDB, simply just change to LONGTEXT. ;-)
I think you are getting error for JSON datatype.
For Mysql 5.7 you can get help from below link.
https://dev.mysql.com/doc/refman/5.7/en/json.html
You can check vesrion using below query.
select version() as 'mysql version'
"JSON" is parsed in the server. JSON is one of the points of divergence.
MySQL 5.7 introduced the JSON datatype, which matches your syntax.
MariaDB 10.0.16 introduced a ENGINE=CONNECT table_type=JSON which does not match your attempted syntax.
You have given single quotes in your index definitions instead of backticks
Try this:
CREATE TABLE `e_store`.`products`(
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT ,
`name` VARCHAR(250) NOT NULL ,
`brand_id` INT UNSIGNED NOT NULL ,
`category_id` INT UNSIGNED NOT NULL ,
`attributes` JSON NOT NULL ,
PRIMARY KEY(`id`) ,
INDEX `CATEGORY_ID`(`category_id` ASC) , -- Changed single quotes to backticks
INDEX `BRAND_ID`(`brand_id` ASC) , -- Changed single quotes to backticks
CONSTRAINT `brand_id` FOREIGN KEY(`brand_id`) REFERENCES `e_store`.`brands`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE ,
CONSTRAINT `category_id` FOREIGN KEY(`category_id`) REFERENCES `e_store`.`categories`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE
);

Facing error while updating size of table-field in sql server 2010

I'm using sql server 2010 that contains bulk amount of data. i am facing error while updating the siz of one of the field in one of table.
code
CREATE TABLE [dbo].[Ayyat_Translation_Language_old_20131209] (
[Ayat_Translation_Language_ID] INT IDENTITY (1, 1) NOT NULL,
[Translation_Laanguage_ID] INT NULL,
[Juz_ID] INT NULL,
[Surah_ID] INT NOT NULL,
[Ayat_Description] NVARCHAR (3900) COLLATE Arabic_CI_AI_KS_WS NOT NULL,
[Ayat_No] INT NULL,
PRIMARY KEY CLUSTERED ([Ayat_Translation_Language_ID] ASC),
CONSTRAINT [fkey2] FOREIGN KEY ([Translation_Laanguage_ID]) REFERENCES [dbo].[Translation_Language] ([TransLation_Language_ID]) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT [fkey0] FOREIGN KEY ([Juz_ID]) REFERENCES [dbo].[Juz] ([Juz_ID]),
CONSTRAINT [fkey1] FOREIGN KEY ([Surah_ID]) REFERENCES [dbo].[Surah] ([Surah_ID]) ON DELETE CASCADE ON UPDATE CASCADE
);
when i try to change the size of [Ayat_Description] from 3900 to 5000, it shows random error. how to fix it ?
nvarchar [ ( n | max ) ]
Variable-length Unicode string data. n defines the string length and can be a value from 1 through 4,000. max indicates that the maximum storage size is 2^31-1 bytes (2 GB). The storage size, in bytes, is two times the actual length of data entered + 2 bytes.
You will need to enter either 4000 or max, in case you need to store more than 4000 characters

MySQL: Error 1628: Comment for table 'customer' is too long (max = 60)

After fixing Error 1253 (MySQL: Unable to fulling forward engineering Sakila (sample) into server), I have Error 1628.
Executing SQL script in server
ERROR: Error 1628: Comment for table 'customer' is too long (max = 60)
Scripts:
CREATE TABLE IF NOT EXISTS `sakila`.`customer` (
`customer_id` SMALLINT(5) UNSIGNED NOT NULL AUTO_INCREMENT ,
`store_id` TINYINT(3) UNSIGNED NOT NULL ,
`first_name` VARCHAR(45) NOT NULL ,
`last_name` VARCHAR(45) NOT NULL ,
`email` VARCHAR(50) NULL DEFAULT NULL ,
`address_id` SMALLINT(5) UNSIGNED NOT NULL ,
`active` TINYINT(1) NOT NULL DEFAULT TRUE ,
`create_date` DATETIME NOT NULL ,
`last_update` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ,
PRIMARY KEY (`customer_id`) ,
INDEX `idx_fk_store_id` (`store_id` ASC) ,
INDEX `idx_fk_address_id` (`address_id` ASC) ,
INDEX `idx_last_name` (`last_name` ASC) ,
CONSTRAINT `fk_customer_address`
FOREIGN KEY (`address_id` )
REFERENCES `sakila`.`address` (`address_id` )
ON DELETE RESTRICT
ON UPDATE CASCADE,
CONSTRAINT `fk_customer_store`
FOREIGN KEY (`store_id` )
REFERENCES `sakila`.`store` (`store_id` )
ON DELETE RESTRICT
ON UPDATE CASCADE)
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8
COMMENT 'Table storing all customers. Holds foreign keys to the address table and the store table where this customer is registered.\n\nBasic information about the customer like first and last name are stored in the table itself. Same for the date the record was created and when the information was last updated.'
SQL script execution finished: statements: 3 succeeded, 1 failed
As an addition: More current versions (5.6.X) allow longer comments. Unfortunately this length differs from the type of comment:
For tables: "A comment for the table, up to 2048 characters long."
For columns: "A comment for a column can be specified with the COMMENT option, up to 1024 characters long."
For INDEX: "In MySQL 5.6, index definitions can include an optional comment of up to 1024 characters."
For PARTITION: "Beginning with MySQL 5.6.6, the maximum length for a partition comment is 1024 characters. (Previously, this limit was not explicitly defined.)"
Source: http://dev.mysql.com/doc/refman/5.6/en/create-table.html
As stated in the MySQL docs, a comment is limited to 255 characters: http://dev.mysql.com/doc/refman/5.1/en/create-table.html#id3411882. Your comment is 305 characters, and it would seem, from the error message, that your particular MySQL install has a 60 character limit.