MySQL fulltext search does not work - php

I have a MySQL table structured like this:
$sql = "CREATE TABLE test(
id INT NOT NULL,
title VARCHAR(512) NOT NULL COLLATE utf8_general_ci,
body TEXT NOT NULL COLLATE utf8_general_ci,
dateStored VARCHAR(32) NOT NULL COLLATE utf8_general_ci,
fileName VARCHAR(128) NOT NULL COLLATE utf8_general_ci,
FOREIGN KEY(id) REFERENCES `database`.`parent`(id)
);";
My storage engine is MYISAM.
Now, when I want to search in body field with the MATCH - AGAINST, there is no result…
This is my try:
$sql2 = "SELECT * FROM database.test
WHERE MATCH(body) AGAINST('?')";
$prepare = $pdo->prepare($sql2);
$prepare->execute( array( $pattern ) );
$fetch = $prepare->fetchAll();
It seems very basic but still my code do not work. Would you tell me what is wrong with my code?
Is this because of I have a field with references to another table?

Add more data. By default MySQL will ignore any word that is in 50% or more of the rows in the table as it considers it would be a 'noise' word.
With very few rows in a table, it is common to hit this 50% limit often (ie. if you have two rows, every word is in at least 50% of the rows!).

I think you are missing the FULLTEXT index on your field. You need to have a FULLTEXT index on a column to do MATCH AGAINST searches.
Either declare the FULLTEXT index with the table or alter your current table to include the index.
ALTER TABLE `test` ADD FULLTEXT (`body`)
Also, as some others have said, there is a cut off to the word length and there is also the 50% threshold that will prevent results from showing.

Try IN BOOLEAN MODE. This will not ignore any rows.
http://dev.mysql.com/doc/refman/5.6/en/fulltext-boolean.html

For MySQL versions 5.6+
You just need to add a FULLTEXT INDEX altering the table like Crackertastic described or define it directly in the CREATE TABLE statement.
Here is a working example:
-- DROP TABLE child;
-- DROP TABLE parent;
CREATE TABLE parent (
id INT NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB; -- or MyISAM
CREATE TABLE child(
id INT NOT NULL,
title VARCHAR(512) NOT NULL COLLATE utf8_general_ci,
body TEXT NOT NULL COLLATE utf8_general_ci,
date_stored VARCHAR(32) NOT NULL COLLATE utf8_general_ci,
file_name VARCHAR(128) NOT NULL COLLATE utf8_general_ci,
parent_id INT NOT NULL,
PRIMARY KEY (id),
FOREIGN KEY (parent_id) REFERENCES parent(id),
FULLTEXT (body)
) ENGINE=InnoDB; -- or MyISAM
INSERT INTO child (id, title, body, date_stored, file_name, parent_id) VALUES('1','test title 1','test body 1','22.05.2014','file1.txt',5);
INSERT INTO child (id, title, body, date_stored, file_name, parent_id) VALUES('2','asd','qwer','31.07.2019','yxcv.txt',6);
INSERT INTO child (id, title, body, date_stored, file_name, parent_id) VALUES('3','gfdsa','trewq','21.04.2015','hjkl.txt',7);
SELECT
*
FROM
child
WHERE
MATCH(body) AGAINST('qwer')
;
The SELECT request returns the entry with the id = 2.
For older MySQL versions
In MySQL vesions older than 5.6 was not possible to define a FULLTEXT INDEX on an InnoDB table.
From the MySQL 5.5 docu:
Full-text indexes can be used only with MyISAM tables. (In MySQL 5.6 and up, they can also be used with InnoDB tables.)
So, one had to decide between using of FOREIGN KEY and FULLTEXT INDEX and choose the storage engine -- InnoDB or MyISAM. Since InnoDB supported FOREIGN KEY constraints, but didn't support FULLTEXT indexes.
An attempt to create a FULLTEXT INDEX on an InnoDB table
-- DROP TABLE child;
-- DROP TABLE parent;
CREATE TABLE parent (
id INT NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB;
CREATE TABLE child(
id INT NOT NULL,
title VARCHAR(512) NOT NULL COLLATE utf8_general_ci,
body TEXT NOT NULL COLLATE utf8_general_ci,
date_stored VARCHAR(32) NOT NULL COLLATE utf8_general_ci,
file_name VARCHAR(128) NOT NULL COLLATE utf8_general_ci,
parent_id INT NOT NULL,
PRIMARY KEY (id),
FOREIGN KEY (parent_id) REFERENCES parent(id)
) ENGINE=InnoDB;
ALTER TABLE `child` ADD FULLTEXT (`body`);
failed with an error:
Query: ALTER TABLE `child` ADD FULLTEXT (`body`)
Error Code: 1214
The used table type doesn't support FULLTEXT indexes
So, you had to use MyISAM for FULLTEXT INDEX. Then you just need to add a FULLTEXT INDEX altering the table like Crackertastic described or define it directly in the CREATE TABLE statement.
Here is a working example:
-- DROP TABLE child;
-- DROP TABLE parent;
CREATE TABLE parent (
id INT NOT NULL,
PRIMARY KEY (id)
) ENGINE=MyISAM;
CREATE TABLE child(
id INT NOT NULL,
title VARCHAR(512) NOT NULL COLLATE utf8_general_ci,
body TEXT NOT NULL COLLATE utf8_general_ci,
date_stored VARCHAR(32) NOT NULL COLLATE utf8_general_ci,
file_name VARCHAR(128) NOT NULL COLLATE utf8_general_ci,
parent_id INT NOT NULL,
PRIMARY KEY (id),
FULLTEXT (body)
) ENGINE=MyISAM;
INSERT INTO child (id, title, body, date_stored, file_name, parent_id) VALUES('1','test title 1','test body 1','22.05.2014','file1.txt',5);
INSERT INTO child (id, title, body, date_stored, file_name, parent_id) VALUES('2','asd','qwer','31.07.2019','yxcv.txt',6);
INSERT INTO child (id, title, body, date_stored, file_name, parent_id) VALUES('3','gfdsa','trewq','21.04.2015','hjkl.txt',7);
SELECT
*
FROM
child
WHERE
MATCH(body) AGAINST('qwer')
;
The SELECT request returns the entry with the id = 2.

Related

Foreign key constraint makes SELECT query return 0 rows

I've been given this database structure:
DROP TABLE IF EXISTS `account`;
CREATE TABLE IF NOT EXISTS `account` (
`accountType` varchar(120) NOT NULL,
PRIMARY KEY (`accountType`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
DROP TABLE IF EXISTS `username`;
CREATE TABLE IF NOT EXISTS `username` (
`usernameID` int(11) NOT NULL AUTO_INCREMENT,
`password` varchar(200) NOT NULL,
`name` varchar(200) NOT NULL,
`phoneNr` int(15) NOT NULL,
`email` varchar(120) NOT NULL,
`accountType` varchar(120) NOT NULL,
PRIMARY KEY (`usernameID`),
KEY `accountType` (`accountType`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
ALTER TABLE `username`
ADD CONSTRAINT `username_ibfk_1` FOREIGN KEY (`accountType`) REFERENCES `account` (`accountType`) ON DELETE CASCADE ON UPDATE CASCADE;
COMMIT;
Now, I want to SELECT a user from the username table. In MySQL workbench I get the results I'm looking for with:
SELECT name FROM username;
However, when using a mysqli query in PHP i get num_rows => 0 in my result object, like this:
(The var_dump above the result object is the query I'm sending in)
It works if I remove the KEY from the username table, so I assume that's where the problem lies. How should I alter my SELECT query?
I believe name is a reserved word in MySQL. You may just need to escape it using the backtick character like so,
SELECT `name` FROM username;
See Keywords and Reserved Words.
For some reason it seems like InnoDB was the issue. As soon as I removed ENGINE=InnoDB from the username table, everything worked.

auto increment field gives error

How to make column autoincrement if other fields are alresdy defined in mysql?
Error
SQL query:
ALTER TABLE `registration` ADD `rid` INT NOT NULL AUTO_INCREMENT FIRST ,
ADD PRIMARY KEY ( `rid` )
MySQL said: Documentation
#1068 - Multiple primary key defined
Here is ddl
Field Type Collation Attributes Null Default Extra Action
rname varchar(255) latin1_swedish_ci No None Browse distinct values Change Drop Primary Unique Index Fulltext
rmobile varchar(255) latin1_swedish_ci No None Browse distinct values Change Drop Primary Unique Index Fulltext
first_name varchar(37) latin1_swedish_ci No None Browse distinct values Change Drop Primary Unique Index Fulltext
last_name varchar(27) latin1_swedish_ci No None Browse distinct values Change Drop Primary Unique Index Fulltext
date_of_birth varchar(45) latin1_swedish_ci No None Browse distinct values Change Drop Primary Unique Index Fulltext
address varchar(200) latin1_swedish_ci No None Browse distinct values Change Drop Primary Unique Index Fulltext
city varchar(150) latin1_swedish_ci No None Browse distinct values Change Drop Primary Unique Index Fulltext
state varchar(200) latin1_swedish_ci No None Browse distinct values Change Drop Primary Unique Index Fulltext
postal_code varchar(67) latin1_swedish_ci No None Browse distinct values Change Drop Primary Unique Index Fulltext
mobile_no varchar(18) latin1_swedish_ci No None Browse distinct values Change Drop Primary Unique Index Fulltext
email_id varchar(99) latin1_swedish_ci No None Browse distinct values Change Drop Primary Unique Index Fulltext
password varchar(25) latin1_swedish_ci No None Browse distinct values Change Drop Primary Unique Index Fulltext
payment bigint(50) No None Browse distinct values Change Drop Primary Unique Index Fulltext
pay tinyint(1) No None Browse distinct values Change Drop Primary Unique Index Fulltext
status tinyint(1) No None Browse distinct values Change Drop Primary Unique Index Fulltext
dt timestamp Yes NULL Browse distinct values Change Drop Primary Unique Index Fulltext
As the error states, you already have a primary key in the table and you cannot have two columns as a primary key in a table. So make you new column UNIQUE and not a PK:
ALTER TABLE `registration` ADD `rid` INT NOT NULL AUTO_INCREMENT UNIQUE

AUTO_INCREMENT in two places

I came across following sql statements and you can see that AUTO_INCREMENT is in two different places. Can you explain the different, I know the first one is auto incrementing id. But what does the second one mean?
CREATE TABLE `categories`(
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(100) NOT NULL,
`image_path` varchar(200) NOT NULL,
PRIMARY KEY(`id`)
) ENGINE = InnoDB;
Second statement.
CREATE TABLE `categories`(
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(100) NOT NULL,
`image_path` varchar(200) NOT NULL,
PRIMARY KEY(`id`)
) ENGINE = InnoDB DEFAULT CHARSET = latin1 AUTO_INCREMENT=4 ;
I referenced http://dev.mysql.com/doc/refman/5.0/en/example-auto-increment.html. But I couldn't find anything.
The AUTO_INCREMENT in the second statement sets the first number to be used in the id at 4.
`id` int(11) NOT NULL AUTO_INCREMENT
Sets the column name and tells the DB to auto increment the number when a new row is added.
) ENGINE = InnoDB DEFAULT CHARSET = latin1 AUTO_INCREMENT=4 ;
Sets the Engine used for the table, the charset and that it should start numbering at 4, not 1.
CREATE TABLE explains this in a bit more detail.
AUTO_INCREMENT
The initial AUTO_INCREMENT value for the table. In MySQL 5.0, this
works for MyISAM and MEMORY tables. It is also supported for InnoDB as
of MySQL 5.0.3.

Cannot create table errno : 150 on Mysql

i get another errno 150 on mysql. i already look at table engine, column type, but no luck, its nothing wrong in my view.
where im going wrong this time?
i get error when creating tag table that relate to image_tag and tag_lang.
-- -----------------------------------------------------
-- Table `ratna`.`image_tag`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `ratna`.`image_tag` ;
CREATE TABLE IF NOT EXISTS `ratna`.`image_tag` (
`id` INT(11) NOT NULL ,
`tag` INT(11) NOT NULL ,
PRIMARY KEY (`id`, `tag`) ,
INDEX `image_fk` (`id` ASC) ,
CONSTRAINT `image_fk`
FOREIGN KEY (`id` )
REFERENCES `ratna`.`image` (`id` )
ON DELETE CASCADE
ON UPDATE CASCADE)
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8;
-- -----------------------------------------------------
-- Table `ratna`.`tag_lang`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `ratna`.`tag_lang` ;
CREATE TABLE IF NOT EXISTS `ratna`.`tag_lang` (
`id` INT(11) NOT NULL ,
`lang` INT(20) NOT NULL ,
`tag_desc` VARCHAR(200) CHARACTER SET 'utf8' COLLATE 'utf8_unicode_ci' NOT NULL ,
PRIMARY KEY (`id`, `lang`) )
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8
COLLATE = utf8_general_ci;
-- -----------------------------------------------------
-- Table `ratna`.`tag`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `ratna`.`tag` ;
CREATE TABLE IF NOT EXISTS `ratna`.`tag` (
`id` INT(11) NOT NULL AUTO_INCREMENT ,
`name` VARCHAR(50) CHARACTER SET 'utf8' COLLATE 'utf8_unicode_ci' NOT NULL ,
`seq` INT(11) NOT NULL ,
PRIMARY KEY (`id`) ,
INDEX `image_tag_fk` (`id` ASC) ,
INDEX `tag_lang` (`id` ASC) ,
CONSTRAINT `image_tag_fk`
FOREIGN KEY (`id` )
REFERENCES `ratna`.`image_tag` (`tag` )
ON DELETE CASCADE
ON UPDATE CASCADE,
CONSTRAINT `tag_lang`
FOREIGN KEY (`id` )
REFERENCES `ratna`.`tag_lang` (`id` )
ON DELETE CASCADE
ON UPDATE CASCADE)
ENGINE = InnoDB
AUTO_INCREMENT = 13
DEFAULT CHARACTER SET = utf8
COLLATE = utf8_general_ci;
This:
REFERENCES `ratna`.`image_tag` (`tag` )
is not valid, because image_tag does not have any index that begins with tag. As explained in the documentation:
InnoDB permits a foreign key to reference any index column or group of columns. However, in the referenced table, there must be an index where the referenced columns are listed as the first columns in the same order.
("The referenced table" in this case is image_tag, and "the referenced columns" are just tag.)
First google result for mysql error 150 shows:
If you re-create a table that was dropped, it must have a definition that conforms to the foreign key constraints referencing it. It must have the right column names and types, and it must have indexes on the referenced keys, as stated earlier. If these are not satisfied, MySQL returns error number 1005 and refers to error 150 in the error message.
If MySQL reports an error number 1005 from a CREATE TABLE statement, and the error message refers to error 150, table creation failed because a foreign key constraint was not correctly formed. Similarly, if an ALTER TABLE fails and it refers to error 150, that means a foreign key definition would be incorrectly formed for the altered table. You can use SHOW ENGINE INNODB STATUS to display a detailed explanation of the most recent InnoDB foreign key error in the server.
http://dev.mysql.com/doc/refman/5.5/en/innodb-foreign-key-constraints.html
in my case it was issue of
foreign key (table_column_name_in_smaller_case) references
primary_key_table_in_upper_case (table_column_name_in_smaller_case)
since my primary key table is in Lower case, i changed this upper foreign key reference from
*primary_key_table_in_upper_case*
to
*primary_key_table_in_lower_case*
and it worked

SQL Syntax Error (phpMyAdmin)

What's wrong with this SQL statement:
ALTER TABLE `tbl_issue`
ADD CONSTRAINT `FK_issue_requester`
FOREIGN KEY (`requester_id`) REFERENCES `tbl_user` (`id`) ON DELETE CASCADE ON UPDATE RESTRICT;
I have tables called tbl_issue and tbl_user within a database called trackstar_dev.
phpMyAdmin said:
#1005 - Can't create table 'trackstar_dev.#sql-1a4_9d' (errno: 121) (Details...)
The most common reason for this error is that the foreign key constraint have the same name as in another table. Foreign keys' names must be unique in the database (not just on table level). Do you have requester_id in another table in your database?
you will get this message if you're trying to add a constraint with a name that's already used somewhere else, c you will get this message if you're trying to add a constraint with a name that's already used somewhere else . change it and it will be ok :)
I had this same problem. Drop all the tables in your database and then use the SQL code below to recreate them. I assume you are following the example in the agile web development with Yii 1.1 and php 5
- Disable foreign keys
SET FOREIGN_KEY_CHECKS = 0 ;# MySQL returned an empty result set (i.e. zero rows).
-- Create tables section -------------------------------------------------
-- Table tbl_project
CREATE TABLE IF NOT EXISTS `tbl_project` (
`id` INTEGER NOT NULL auto_increment,
`name` varchar(128) NOT NULL,
`description` text NOT NULL,
`create_time` DATETIME default NULL,
`create_user_id` INTEGER default NULL,
`update_time` DATETIME default NULL,
`update_user_id` INTEGER default NULL,
PRIMARY KEY (`id`)
) ENGINE = InnoDB
;# MySQL returned an empty result set (i.e. zero rows).
-- DROP TABLE IF EXISTS `tbl_issue` ;
CREATE TABLE IF NOT EXISTS `tbl_issue`
(
`id` INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
`name` varchar(256) NOT NULL,
`description` varchar(2000),
`project_id` INTEGER,
`type_id` INTEGER,
`status_id` INTEGER,
`owner_id` INTEGER,
`requester_id` INTEGER,
`create_time` DATETIME,
`create_user_id` INTEGER,
`update_time` DATETIME,
`update_user_id` INTEGER
) ENGINE = InnoDB
;# MySQL returned an empty result set (i.e. zero rows).
-- DROP TABLE IF EXISTS `tbl_user` ;
-- Table User
CREATE TABLE IF NOT EXISTS `tbl_user`
(
`id` INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
`email` Varchar(256) NOT NULL,
`username` Varchar(256),
`password` Varchar(256),
`last_login_time` Datetime,
`create_time` DATETIME,
`create_user_id` INTEGER,
`update_time` DATETIME,
`update_user_id` INTEGER
) ENGINE = InnoDB
;# MySQL returned an empty result set (i.e. zero rows).
-- DROP TABLE IF EXISTS `tbl_project_user_assignment` ;
-- Table User
CREATE TABLE IF NOT EXISTS `tbl_project_user_assignment`
(
`project_id` Int(11) NOT NULL,
`user_id` Int(11) NOT NULL,
`create_time` DATETIME,
`create_user_id` INTEGER,
`update_time` DATETIME,
`update_user_id` INTEGER,
PRIMARY KEY (`project_id`,`user_id`)
) ENGINE = InnoDB
;# MySQL returned an empty result set (i.e. zero rows).
-- The Relationships
ALTER TABLE `tbl_issue` ADD CONSTRAINT `FK_issue_project` FOREIGN KEY (`project_id`) REFERENCES `tbl_project` (`id`) ON DELETE CASCADE ON UPDATE RESTRICT;# MySQL returned an empty result set (i.e. zero rows).
ALTER TABLE `tbl_issue` ADD CONSTRAINT `FK_issue_owner` FOREIGN KEY (`owner_id`) REFERENCES `tbl_user` (`id`) ON DELETE CASCADE ON UPDATE RESTRICT;# MySQL returned an empty result set (i.e. zero rows).
ALTER TABLE `tbl_issue` ADD CONSTRAINT `FK_issue_requester` FOREIGN KEY (`requester_id`) REFERENCES `tbl_user` (`id`) ON DELETE CASCADE ON UPDATE RESTRICT;# MySQL returned an empty result set (i.e. zero rows).
ALTER TABLE `tbl_project_user_assignment` ADD CONSTRAINT `FK_project_user` FOREIGN KEY (`project_id`) REFERENCES `tbl_project` (`id`) ON DELETE CASCADE ON UPDATE RESTRICT;# MySQL returned an empty result set (i.e. zero rows).
ALTER TABLE `tbl_project_user_assignment` ADD CONSTRAINT `FK_user_project` FOREIGN KEY (`user_id`) REFERENCES `tbl_user` (`id`) ON DELETE CASCADE ON UPDATE RESTRICT;# MySQL returned an empty result set (i.e. zero rows).
-- Insert some seed data so we can just begin using the database
INSERT INTO `tbl_user`
(`email`, `username`, `password`)
VALUES
('test1#notanaddress.com','Test_User_One', MD5('test1')),
('test2#notanaddress.com','Test_User_Two', MD5('test2'))
;# 2 rows affected.
-- Enable foreign keys
SET FOREIGN_KEY_CHECKS = 1 ;# MySQL returned an empty result set (i.e. zero rows).

Categories