10.4.24-MariaDB - Foreign key constraint is incorrectly formed - mariadb

In person_addresses table i am getting error Foreign key constraint is incorrectly formed. My Version is 10.4.24-MariaDB
CREATE TABLE persons (
person_id int(11) NOT NULL AUTO_INCREMENT,
name varchar(255) NOT NULL,
email varchar(50) DEFAULT NULL,
phone int(11) DEFAULT NULL,
bio text DEFAULT NULL,
dob date DEFAULT NULL,
gender enum('Male','Female','Other') NOT NULL,
status tinyint(4) NOT NULL,
created_at timestamp NOT NULL DEFAULT current_timestamp(),
PRIMARY KEY (person_id),
UNIQUE KEY email (email),
UNIQUE KEY phone (phone)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE person_addresses (
person_id int(11) NOT NULL ,
address text NOT NULL,
created_at timestamp NOT NULL DEFAULT current_timestamp(),
UNIQUE KEY uc_person_address (person_id,address),
CONSTRAINT fk_person FOREIGN KEY (person_id) REFERENCES persons(person_id) ON UPDATE CASCADE ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
More Detailed Error
------------------------
LATEST FOREIGN KEY ERROR
------------------------
2023-01-11 12:41:52 0x421c Error in foreign key constraint of table `test`.`person_addresses`:
There is no index in table ```test``.``person_addresses``` where the columns appear
as the first columns. Constraint:
FOREIGN KEY (person_id) REFERENCES persons (person_id) ON UPDATE CASCADE ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
Please refer to https://mariadb.com/kb/en/library/foreign-keys/ for correct foreign key definition.Create table `test`.`person_addresses` with foreign key constraint failed. There is no index in the referenced table where the referenced columns appear as the first columns near ' FOREIGN KEY (person_id) REFERENCES persons (person_id) ON UPDATE CASCADE ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4'.

I think I found a matching bug report in MariaDB: https://jira.mariadb.org/browse/MDEV-29717
The issue is that if the index required for the foreign key is very large, the index is created automatically. But this fails if that index is larger than the index size limit for the storage engine (this should be 3072 bytes in the version of MariaDB you are using, because it defaults to DYNAMIC row format with innodb_large_prefix=on). The text type in your index is too large to be indexed without defining an index prefix. But foreign keys can't use indexes defined with index prefixes.
Unfortunately, because foreign keys are implemented deep in the storage engine, there is little opportunity for a more informative error message to be revealed. This is a problem with the implementation of pluggable storage engines.
The solution in your case should be to change the address column type. It cannot be text, it can only be a varchar that is not too long for the index prefix length limit.
For example, I tested with MariaDB 10.4. https://dbfiddle.uk/5jTX8iFt It fails if address is text, and it works fine if address is varchar(255). I did not test other lengths, I'll leave that to you.
I doubt you need text for an address anyway. Does anyone have an address that requires 64KB?

Related

JBPM issue with Maria DB Galera were Primary key mandatory

JBPM issue with Maria DB Galera were Primary key mandatory.
Some tables in JBPM db schema have no primary key.
If I add a primary key column along with them what will be the impact?
Is there nay other way I can get ride of this problem?
Currently we have Mariadb as the only database option to use.
create table EventTypes (
InstanceId bigint not null,
element varchar(255)
) ENGINE=InnoDB;
create table PeopleAssignments_PotOwners (
task_id bigint not null,
entity_id varchar(255) not null
) ENGINE=InnoDB;
Source for MariaDB primary Key mandatory:
mariadb-galera-cluster-known-limitations
Please help.
PeopleAssignments_PotOwners looks like a many:many mapping table between tasks and entities?? If so, then the 'natural' PRIMARY KEY would be
PRIMARY KEY(task_id, entity_id)
(in either order).
Perhaps ditto for the other table?
More discussion of efficiency in many:many tables: http://mysql.rjweb.org/doc.php/index_cookbook_mysql#many_to_many_mapping_table
If you don't have a 'natural' primary key composed of one (or more) columns, add
id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY

MariaDB 10.1 Truncate table cascade syntax error

When i try to execute the following sql statemant MariaDB give an error:
SQL: TRUNCATE $table CASCADE;
SQLSTATE[42000]: Syntax error or access violation: 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 'CASCADE' at line 1 (SQL: TRUNCATE wortmann_products CASCADE;)
is cascade removed in MariaDB or is there something wrong whit the sql statement?
If you are looking to cascade out deletes and updates then the definition has to be stored when the table is created or altered, and will apply to the keys (or FK's in associated tables) allowing child records to be deleted in associated table when parent record is deleted. There are plenty of resources on this, I have listed one here: https://mariadb.com/kb/en/the-mariadb-library/foreign-keys/ - Taken from this resource is the example below:
CREATE TABLE author (
id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL
) ENGINE = InnoDB;
CREATE TABLE book (
id MEDIUMINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(200) NOT NULL,
author_id SMALLINT UNSIGNED NOT NULL,
CONSTRAINT `fk_book_author`
FOREIGN KEY (author_id) REFERENCES author (id)
ON DELETE CASCADE
ON UPDATE RESTRICT
) ENGINE = InnoDB;

How to get the names of foreign key constraints in SQLite?

Does SQLite indeed have a limitation that it is not possible to retrieve the name of a foreign key? I am asking because I couldn't find this limitation mentioned anywhere in their documentation.
For example, I run the following script:
CREATE TABLE
users (
id INTEGER NOT NULL PRIMARY KEY,
first_name TEXT NOT NULL,
last_name TEXT NOT NULL
) ;
CREATE TABLE
orders (
id INTEGER NOT NULL PRIMARY KEY,
user_id INTEGER NOT NULL,
CONSTRAINT fk_users FOREIGN KEY (user_id) REFERENCES users(id)
) ;
Now I would like to check that the key "fk_users" was created indeed, so I run the following PRAGMA:
PRAGMA foreign_key_list(orders);
I would expect to see the name of my foreign key in the first column, but I am seeing some "0" value instead. Moreover, if I create multiple foreign keys with custom names, they are all called either "0" or "1".
Is this indeed a limitation of SQLite, or am I missing something?
There is no mechanism to extract the constraint name.
The table sqlite_master stores a CREATE command in the column "sql". You could query that command and do some parsing to extract the name of the foreign key. An example for a combined foreign key that works for me:
SELECT sql FROM sqlite_master WHERE name = 'song'
yields
CREATE TABLE "song" (
"songid" INTEGER,
"songartist" TEXT,
"songalbum" TEXT,
"songname" TEXT,
CONSTRAINT "fk__song_album" FOREIGN KEY ("songartist", "songalbum") REFERENCES "album" ("albumartist", "albumname")
)
and contains the name "fk__song_album" of the foreign key.
If one alters the foreign key with a query, the content of the sql column is modified/updated:
The text in the sqlite_master.sql column is a copy of the original CREATE statement text that created the object, except normalized as described above and as modified by subsequent ALTER TABLE statements. The sqlite_master.sql is NULL for the internal indexes that are automatically created by UNIQUE or PRIMARY KEY constraints.
https://www.sqlite.org/fileformat2.html
Extra tip:
In order to see the foreign key information in Navicat (Lite) ... right click on a table and choose "Design table". Then select the foreign keys tab.

MariaDB: ALTER TABLE syntax to add a FOREIGN KEY?

what'S wrong with the following statement?
ALTER TABLE submittedForecast
ADD CONSTRAINT FOREIGN KEY (data) REFERENCES blobs (id);
The error message I am getting is
Can't create table `fcdemo`.`#sql-664_b` (errno: 150 "Foreign key constraint is incorrectly formed")
This works for me on MariaDB 10.1.8:
CREATE TABLE `submittedforecast` (
`id` INT(11) NOT NULL,
`data` INT(11) NOT NULL,
PRIMARY KEY (`id`),
INDEX `data` (`data`)
) ENGINE=InnoDB;
CREATE TABLE `blobs` (
`id` INT(11) NOT NULL,
`content` BLOB NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
ALTER TABLE submittedForecast
ADD CONSTRAINT FOREIGN KEY (data) REFERENCES blobs (id);
Can you give your MariaDB version number and a complete example including the CREATE TABLE statements for submittedForecast and blobs?
No idea if you already solved this but make sure both engines and collations match between tables (e.g: latin1 to latin1 and InnoDB to InnoDB).
I was having the same issue and by switching these I managed to get it working.
I was getting the same issue and after looking at my table structure, found out that my child table's foreign key clause was not referencing the primary key of parent table. Once i changed it to reference to primary key of parent table, the error was gone.
I had the same error and is actually pretty easy to solve, you have name the constraint, something like this should do:
ALTER TABLE submittedForecast ADD CONSTRAINT `fk_submittedForecast`
FOREIGN KEY (data) REFERENCES blobs (id)
If you would like more cohesion also add at the end of the query
ON DELETE CASCADE ON UPDATE RESTRICT
This could also be a different fields error so check if the table key and the foreign key are of the same type and have the same atributes.
I had the same problem, too. When checking the definition of the fields, I noticed that one field was defined as INT and the other as BIGINT. After changing the BIGINT type to INT, I was able to create my foreign key.

Unknown sql(ite) syntax error

Why is the following invalid, i'm at a loss here?
'CREATE TABLE IF NOT EXISTS Mons(id int PRIMARY KEY NOT NULL AUTO_INCREMENT, keyword VARCHAR(255) NOT NULL);'
From node.js's sqlite3, in coffeescript as:
db.parallelize( () ->
db.run('CREATE TABLE IF NOT EXISTS Mons(id int PRIMARY KEY NOT NULL AUTO_INCREMENT, keyword VARCHAR(255) NOT NULL);')
)
Exact error:
Error: SQLITE_ERROR: near "AUTO_INCREMENT": syntax error
at Error (native)
The syntax for an autoincrement primary key in sqlite is
INTEGER PRIMARY KEY AUTOINCREMENT
and not
int PRIMARY KEY NOT NULL AUTO_INCREMENT
If you omit the AUTOINCREMENT keyword, you'll get slightly different autoincrement behavior.
Using AUTO_INCREMENT isn't the best idea unless you want unique keys for the lifetime of your db. If you delete a record, that id can never be used again. This constraint will slow your database down and use more memory so if you don't need unique keys, I would suggest dropping this as PRIMARY KEY already has a constraint to resist any identical primary keys.

Resources