Incorrect prefix key MySQL [duplicate] - php

This question already has answers here:
What is wrong with my SQL here? #1089 - Incorrect prefix key
(15 answers)
Closed 7 years ago.
I have a problem creating a table with phpmyadmin, which gives me the following error:
#1089 - Incorrect prefix key; the used key part isn't a string, the used length is longer than the key part, or the storage engine doesn't support unique prefix keys
This is the query that I do:
CREATE TABLE `b2b`.`users` ( `id` BIGINT NOT NULL AUTO_INCREMENT ,
`name` VARCHAR(30) NOT NULL ,
`surnames` VARCHAR(80) NOT NULL ,
`birthdate` DATE NOT NULL ,
`drivingdoc` VARCHAR(20) NOT NULL ,
`acdate` DATE NOT NULL ,
`countrydoc` VARCHAR(20) NOT NULL ,
`province` VARCHAR(20) NOT NULL ,
`locality` VARCHAR(35) NOT NULL ,
`address` VARCHAR(150) NOT NULL ,
`number` VARCHAR(20) NOT NULL ,
`flat` VARCHAR(20) NOT NULL ,
`door` VARCHAR(20) NOT NULL ,
`description` VARCHAR(2000) NOT NULL ,
PRIMARY KEY (`id`(7))) ENGINE = InnoDB;
Using MariaDB in ubuntu minimal.

The problem is:
PRIMARY KEY (`id`(7))
You cannot use part of a number as a key, you have to use the whole thing. Also, specifying lengths for numeric types is useless at best, and damaging at worst.
Change to:
PRIMARY KEY (`id`)

That Primary Key syntax is nothing I've ever seen before. Try this:
CREATE TABLE `b2b`.`users` (
`id` BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
....
) ENGINE = InnoDB;
Or if you want
CREATE TABLE `b2b`.`users` (
`id` BIGINT NOT NULL AUTO_INCREMENT,
....
PRIMARY KEY (id)
) ENGINE = InnoDB;

You have several errors in your sql, so try to find the difference with this sql
CREATE TABLE `b2b`.`users` ( `id` INT(7) NOT NULL AUTO_INCREMENT ,
`name` VARCHAR(30) NOT NULL ,
`surnames` VARCHAR(80) NOT NULL ,
`birthdate` DATE NOT NULL ,
`drivingdoc` VARCHAR(20) NOT NULL ,
`acdate` DATE NOT NULL ,
`countrydoc` VARCHAR(20) NOT NULL ,
`province` VARCHAR(20) NOT NULL ,
`locality` VARCHAR(35) NOT NULL ,
`address` VARCHAR(150) NOT NULL ,
`number` VARCHAR(20) NOT NULL ,
`flat` VARCHAR(20) NOT NULL ,
`door` VARCHAR(20) NOT NULL ,
`description` VARCHAR(255) NOT NULL ,
PRIMARY KEY (`id`)) ENGINE = InnoDB;

Related

MySQL error 1064 on creating a table query

CREATE TABLE `chuchutvlogin`. (
`id` INT NOT NULL AUTO_INCREMENT ,
`username` VARCHAR(20) NOT NULL ,
`gender` CHAR(1) NOT NULL ,
`email` VARCHAR(50) NOT NULL ,
`password` VARCHAR(20) NOT NULL ,
`number` BIGINT(10) NOT NULL ,
PRIMARY KEY (`id`)
) ENGINE = InnoDB;
what's issue?
i was creating a login databse and error #1064 came syntax error in localhost phpmyadmnin
Fix syntax error in your query, remove dot char after table name:
CREATE TABLE chuchutvlogin (
id INT NOT NULL AUTO_INCREMENT,
username VARCHAR(20) NOT NULL,
gender CHAR(1) NOT NULL,
email VARCHAR(50) NOT NULL,
password VARCHAR(20) NOT NULL,
number BIGINT(10) NOT NULL,
PRIMARY KEY (id)
) ENGINE = InnoDB;
dbfiddle

Laravel Morph Many from two columns

I need to find a way to modify the morphMany relationship to morph two different columns. Here is the table create syntax that is being morphed:
CREATE TABLE `user_friendships` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`sender_type` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`sender_id` bigint(20) unsigned NOT NULL,
`recipient_type` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`recipient_id` bigint(20) unsigned NOT NULL,
`status` tinyint(4) NOT NULL DEFAULT '0',
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `user_friendships_sender_type_sender_id_index` (`sender_type`,`sender_id`),
KEY `user_friendships_recipient_type_recipient_id_index` (`recipient_type`,`recipient_id`)
) ENGINE=InnoDB AUTO_INCREMENT=12332 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
Sender and recipient can both be a user. So I want to morph based on whatever column of the two contains the user_id.
This only looks at if the sender is the user, but not the recipient.
return $this->morphMany(Friendship::class, 'sender');
The output of the query from that is:
select * from `user_friendships` where `user_friendships`.`sender_id` = 5971 and `user_friendships`.`sender_id` is not null and `user_friendships`.`sender_type` = "App\\\User"
What we actually want is:
select * from `user_friendships` where (`user_friendships`.`sender_id` = 5971 and `user_friendships`.`sender_id` is not null and `user_friendships`.`sender_type` = "App\\\User") OR (`user_friendships`.`recipient_id` = 5971 and `user_friendships`.`recipient_id` is not null and `user_friendships`.`recipient_type` = "App\\\User")
How do I accomplish this?
https://github.com/staudenmeir/laravel-merged-relations
This composer package was able to solve it.

I got error while entering the primary key in database

Right now, i've created database with having 10 columns in my database but i can't create the database table and i got "#1067 - Invalid default value for 'primary_key" error.
Here is my sql code:
CREATE TABLE `quiz`.`user_details` ( `primary_key` INT(6) UNSIGNED NOT NULL DEFAULT '1' AUTO_INCREMENT , `foreign_key` INT(6) UNSIGNED NOT NULL DEFAULT '1' AUTO_INCREMENT , `firstname` VARCHAR(20) NOT NULL , `lastname` VARCHAR(20) NOT NULL , `username` VARCHAR(20) NOT NULL , `password` VARCHAR(20) NOT NULL , `email` VARCHAR(20) NOT NULL , `phone_number` INT(10) NOT NULL , `address` CHAR(50) NOT NULL , `exam_taking` INT(3) NOT NULL AUTO_INCREMENT , PRIMARY KEY (`primary_key`(6)), UNIQUE `foreign_key` (`foreign_key`)) ENGINE = InnoDB;
Don't add DEFAULT value because you already defined primary key as AUTO INCREMENT.
Possible duplicate.
#1067 - Invalid default value for 'bonusid' how can i fix this error?
You cannot have a default value for auto incrementing fields. Simply change the definition to:
CREATE TABLE `quiz`.`user_details`
(`primary_key` INT(6) UNSIGNED NOT NULL AUTO_INCREMENT,
`foreign_key` INT(6) UNSIGNED NOT NULL AUTO_INCREMENT ,
`firstname` VARCHAR(20) NOT NULL ,
`lastname` VARCHAR(20) NOT NULL ,
`username` VARCHAR(20) NOT NULL ,
`password` VARCHAR(20) NOT NULL ,
`email` VARCHAR(20) NOT NULL ,
`phone_number` INT(10) NOT NULL ,
`address` CHAR(50) NOT NULL ,
`exam_taking` INT(3) NOT NULL AUTO_INCREMENT ,
PRIMARY KEY (`primary_key`),
UNIQUE `foreign_key` (`foreign_key`)) ENGINE = InnoDB;
Note also that a name foreign_key for an attribute which is not a foreign key is really misleading.

error in your SQL syntax check the manual that corresponds to your MySQL server version

CREATE TABLE `mytable` (
`cid` TINYINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`ckey` TINYTEXT UNSIGNED NOT NULL ,
`cdate` TINYTEXT UNSIGNED NOT NULL ,
`ctime` TINYTEXT UNSIGNED NOT NULL ,
`cuser` TINYTEXT UNSIGNED NOT NULL ,
`ctext` LONGTEXT UNSIGNED NOT NULL ,
`cstatus` TINYTEXT UNSIGNED NOT NULL
) ENGINE = MYISAM CHARACTER SET utf8 COLLATE utf8_general_ci
MySQL said:
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 'UNSIGNED NOT NULL, cdate TINYTEXT UNSIGNED NOT NULL, ctime TINYTEXT UNSIGNED' at line 1
Updated full code:
$query = "
CREATE TABLE mytable (
cid INT(1) NOT NULL AUTO_INCREMENT PRIMARY KEY ,
ckey TINYTEXT(10) NOT NULL ,
cdate TINYTEXT(10) NOT NULL ,
ctime TINYTEXT(10) NOT NULL ,
cuser TINYTEXT(10) NOT NULL ,
ctext LONGTEXT(10) NOT NULL ,
cstatus TINYTEXT(10) NOT NULL
) ENGINE = MYISAM CHARACTER SET utf8 COLLATE utf8_general_ci AUTO_INCREMENT = 1;";
You have to specify string max length, like:
CREATE TABLE `mytable` (
`cid` TINYINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`ckey` TINYTEXT(10) UNSIGNED NOT NULL ,
`cdate` TINYTEXT(10) UNSIGNED NOT NULL ,
`ctime` TINYTEXT(10) UNSIGNED NOT NULL ,
`cuser` TINYTEXT(10) UNSIGNED NOT NULL ,
`ctext` LONGTEXT(10) UNSIGNED NOT NULL ,
`cstatus` TINYTEXT(10) UNSIGNED NOT NULL
) ENGINE = MYISAM CHARACTER SET utf8 COLLATE utf8_general_ci
where 10 is your value. Hope to be useful
I don't know if it's answering the question since I tried via php and it was not working so I did it directly
CREATE TABLE `mytable` (
`cid` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`ckey` TINYTEXT NOT NULL ,
`cdate` TINYTEXT NOT NULL ,
`ctime` TINYTEXT NOT NULL ,
`cuser` TINYTEXT NOT NULL ,
`ctext` TEXT NOT NULL ,
`cstatus` TINYINT UNSIGNED NOT NULL
) ENGINE = MYISAM CHARACTER SET utf8 COLLATE utf8_general_ci;

MySql: Need to improve the performance for a query

I need to pump up my query a bit for it's taking way too long on a large DB.
I have the following tables
vb_user
+++++++++++++++++++++++++++++++++
++ userid ++ username ++ posts ++
+++++++++++++++++++++++++++++++++
vb_post
++++++++++++++++++++++++
++ userid ++ dateline ++
++++++++++++++++++++++++
I use this query
SELECT VBU.userid AS USER_ID
, VBU.username AS USER_NAME
, COUNT(VBP.userid) AS NUMBER_OF_POSTS_FOR_30_DAYS
, FROM_UNIXTIME(VBU.joindate) as JOIN_DATE
FROM vb_user AS VBU
LEFT JOIN vb_post AS VBP
ON VBP.userid = VBU.userid
WHERE VBU.joindate BETWEEN '__START_DATE__' AND '__END_DATE__'
AND VBP.dateline BETWEEN VBU.joindate AND DATE_ADD(FROM_UNIXTIME(VBU.joindate), INTERVAL 30 DAY)
GROUP BY VBP.userid
ORDER BY NUMBER_OF_POSTS_FOR_30_DAYS DESC"
I have to select the users who have posted the most from when they joined till 30 days after..... and I can't figure out how to do it withouth the FROM_UNIXTIME function..
But it takes a lot of time. Any thoughts on how to improve the performance for the query?
Here is the output for explain
id,select_type,table,type,possible_keys,key,key_len,ref,rows,Extra
1,SIMPLE,VBP,index,userid,threadid_visible_dateline,18,NULL,2968000,"Using where; Using index; Using temporary; Using filesort"
1,SIMPLE,VBU,eq_ref,PRIMARY,PRIMARY,4,vb_copilul.VBP.userid,1,"Using where"
And here is the info about the tables
Table,"Create Table"
vb_user,"CREATE TABLE `vb_user` (
`userid` int(10) unsigned NOT NULL AUTO_INCREMENT,
`username` varchar(100) NOT NULL DEFAULT '',
`posts` int(10) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`userid`),
KEY `usergroupid` (`usergroupid`),
) ENGINE=MyISAM AUTO_INCREMENT=101076 DEFAULT CHARSET=latin1"
Table,"Create Table"
vb_post,"CREATE TABLE `vb_post` (
`postid` int(10) unsigned NOT NULL AUTO_INCREMENT,
`threadid` int(10) unsigned NOT NULL DEFAULT '0',
`parentid` int(10) unsigned NOT NULL DEFAULT '0',
`username` varchar(100) NOT NULL DEFAULT '',
`userid` int(10) unsigned NOT NULL DEFAULT '0',
`title` varchar(250) NOT NULL DEFAULT '',
`dateline` int(10) unsigned NOT NULL DEFAULT '0',
`pagetext` mediumtext,
`allowsmilie` smallint(6) NOT NULL DEFAULT '0',
`showsignature` smallint(6) NOT NULL DEFAULT '0',
`ipaddress` char(15) NOT NULL DEFAULT '',
`iconid` smallint(5) unsigned NOT NULL DEFAULT '0',
`visible` smallint(6) NOT NULL DEFAULT '0',
`attach` smallint(5) unsigned NOT NULL DEFAULT '0',
`infraction` smallint(5) unsigned NOT NULL DEFAULT '0',
`reportthreadid` int(10) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`postid`),
KEY `userid` (`userid`),
KEY `threadid` (`threadid`,`userid`),
KEY `threadid_visible_dateline` (`threadid`,`visible`,`dateline`,`userid`,`postid`),
KEY `dateline` (`dateline`),
KEY `ipaddress` (`ipaddress`)
) ENGINE=MyISAM AUTO_INCREMENT=3009320 DEFAULT CHARSET=latin1"
Two things you can do to improve the query:
Do not convert VBP.datetime to unix time. Use the BETWEEN query with the dates directly. In your query the server has to convert all dates in the DB to compare them, instead of use the native types. If you are always using the datetime column as unix timestamp, then declare it as Double (I think?) instead of DATETIME (or TIMESTAMP - whatever you have chosen). This way you will speed up other operations too.
Add index to the datetime column to make sure the between query is fast enough.
Everything else looks OK

Categories