PHP/MySQL database question? - php

I have a question I'm trying to have the q_id column take the value of the id column when a tag is submitted I have been trying to do this using PHP but I was thinking should I just add AUTO INCREMENT to the q_id column since but tables are updated when the tag is submited. or is this the wrong way to do it or is there a better way to do this?
Here is the MySQL tables below.
CREATE TABLE q_tags (
q_id INT UNSIGNED NOT NULL,
users_q_id INT UNSIGNED NOT NULL
);
CREATE TABLE tags (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
tag VARCHAR(255) NOT NULL,
PRIMARY KEY (id)
);

AUTO INCREMENT is used mainly to avoid adding the same ID into a table, so that you can keep a loyal index. I'd suggest you add a primary key to the q_tags, and change the current q_id to a foreign key, so that it can become a reference to tags table.
EDIT :
CREATE TABLE q_tags (
q_id INT UNSIGNED NOT NULL AUTO_INCREMENT,
t_id INT UNSIGNED NOT NULL,
users_q_id INT UNSIGNED NOT NULL,
PRIMARY KEY (q_id)
);
CREATE TABLE tags (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
tag VARCHAR(255) NOT NULL,
PRIMARY KEY (id)
);
t_id in the first table is the "foreign key". You can add it as a real mysql foreign key or just keep it this way (if you're planning on be able to "cascade delete" tags and t_tags related, it would matter)

Related

ERROR 1005 (HY000): Can't create table 'db.POSTS' (errno: 150)

Hi I'm having issues creating my post database. I'm trying to make a forenge key to link to my users database. Can someone please help?
Here's the code for my tables :
CREATE TABLE USERS(
UserID int NOT NULL AUTO_INCREMENT,
UserName varchar(255),
UserPassword varchar(255) NOT NULL,
UserEmailAddress varchar(255) NOT NULL,
Admin int DEFAULT 0,
PRIMARY KEY (userID,UserName)
)ENGINE=InnoDB;
CREATE TABLE POSTS(
postID int NOT NULL AUTO_INCREMENT,
postTitle varchar(255) NOT NULL,
postContent varchar(255) NOT NULL,
category varchar(255) NOT NULL,
postDate Date NOT NULL,
postAuthor varchar(255),
tag varchar(255),
PRIMARY KEY(postID),
FOREIGN KEY(postAuthor) REFERENCES USERS(UserName)
)ENGINE=InnoDB;
Here's the last InnoDB error message:
Error in foreign key constraint of table db/POSTS:
FOREIGN KEY(postAuthor) REFERENCES USERS(UserName)
)ENGINE=InnoDB:
Cannot find an index in the referenced table where the
referenced columns appear as the first columns, or column types
in the table and the referenced table do not match for constraint.
Note that the internal storage type of ENUM and SET changed in
tables created with >= InnoDB-4.1.12, and such columns in old tables
cannot be referenced by such columns in new tables.
See http://dev.mysql.com/doc/refman/5.5/en/innodb-foreign-key-constraints.html
for correct foreign key definition.
There really should not be a good reason to have a compound primary key on the first table. So, I think you intend:
CREATE TABLE USERS (
UserID int NOT NULL AUTO_INCREMENT,
UserName varchar(255),
UserPassword varchar(255) NOT NULL,
UserEmailAddress varchar(255) NOT NULL,
Admin int DEFAULT 0,
PRIMARY KEY (userID),
UNIQUE (UserName)
);
CREATE TABLE POSTS (
postID int NOT NULL AUTO_INCREMENT,
postTitle varchar(255) NOT NULL,
postContent varchar(255) NOT NULL,
category varchar(255) NOT NULL,
postDate Date NOT NULL,
postAuthor int,
tag varchar(255),
PRIMARY KEY(postID),
FOREIGN KEY(postAuthor) REFERENCES USERS(UserId)
);
Some notes:
An auto-incremented id is unique on every row. It makes a good primary key.
A primary key can consist of multiple columns (called a composite primary key). However, an auto-incremented id doesn't make much sense as one of the columns. Just use such an id itself.
If you use a composite primary key, then the foreign key references need to include all columns.
I chose UserId for the foreign key reference. You could also use UserName (because it is unique).
UserName is a bad choice for foreign keys, because -- conceivably -- a user could change his or her name.
The error is caused by incorrect foreign key definition. In the concrete case you are missing a complete column in your foreign key definition.
In the USERS table you have defined primary key as composite key of UserID and UserName columns.
CREATE TABLE USERS (
UserID int NOT NULL AUTO_INCREMENT,
UserName varchar(255),
UserPassword varchar(255) NOT NULL,
UserEmailAddress varchar(255) NOT NULL,
Admin int DEFAULT 0,
PRIMARY KEY (UserID,UserName)
) ENGINE=InnoDB;
note that it is good practice to respect case of the identifiers (column names)
In the POSTS table you declared your foreign key to reference only one column in the USERS table, the UserName column. This is incorrect as you need to reference entire primary key of the USERS table which is (UserID, UserName). So to fix the error you need to add one additional column to the POSTS table and change your foreign key definition like this:
CREATE TABLE POSTS(
postID int NOT NULL AUTO_INCREMENT,
postTitle varchar(255) NOT NULL,
postContent varchar(255) NOT NULL,
category varchar(255) NOT NULL,
postDate Date NOT NULL,
authorId int,
postAuthor varchar(255),
tag varchar(255),
PRIMARY KEY(postID),
FOREIGN KEY(authorId, postAuthor) REFERENCES USERS(UserID, UserName)
) ENGINE=InnoDB;
Please look at following fiddle: http://sqlfiddle.com/#!9/92ff1/1
NOTE: If you can you should re-architect this to not use the composite primary key in the USERS table as it does not make sense from what I can see in the displayed code. You can change the tables like this:
CREATE TABLE USERS (
UserID int NOT NULL AUTO_INCREMENT,
UserName varchar(255),
UserPassword varchar(255) NOT NULL,
UserEmailAddress varchar(255) NOT NULL,
Admin int DEFAULT 0,
PRIMARY KEY (UserID)
) ENGINE=InnoDB;
CREATE TABLE POSTS (
postID int NOT NULL AUTO_INCREMENT,
postTitle varchar(255) NOT NULL,
postContent varchar(255) NOT NULL,
category varchar(255) NOT NULL,
postDate Date NOT NULL,
postAuthorID int,
tag varchar(255),
PRIMARY KEY(postID),
FOREIGN KEY(postAuthorID) REFERENCES USERS(UserID)
) ENGINE=InnoDB;;

I want to add multiple data in mysql table with php

I have 1 user and I want to insert more than one language(and degree) to him. How can I do this with php?
My languagetype table(all languages inserted)
CREATE TABLE TLANGUAGETYPE (
ID INT NOT NULL AUTO_INCREMENT,
language VARCHAR(100) NOT NULL,
PRIMARY KEY (ID)
)
My language table connected with user table.
CREATE TABLE TLANGUAGE (
languageID INT NOT NULL AUTO_INCREMENT,
userID INT NOT NULL,
ID INT NOT NULL,
degree FLOAT,
PRIMARY KEY (languageID),
FOREIGN KEY (userID) REFERENCES TUSER(userID),
FOREIGN KEY (ID) REFERENCES TLANGUAGETYPE(ID)
)
Instead of adding the languageId in user Table. You can create a mapping table which just contains the "USERID" and "LanguageID" columns.

mysql 'likes' structure table

I'm working on a web site where users can post articles with this table structure :
CREATE TABLE IF NOT EXISTS `articles` (
`id_articles` int(10) unsigned NOT NULL AUTO_INCREMENT,
`id_users` int(10) unsigned NOT NULL,
`articles` text NOT NULL,
PRIMARY KEY (`id_articles`),
UNIQUE KEY `id_articles` (`id_articles`),
KEY `id_users` (`id_users`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
Each user can 'like' the articles.
Is that the right way below to create a 'like table' :
CREATE TABLE IF NOT EXISTS `articles_likes` (
`id_articles` int(10) unsigned NOT NULL,
`id_users` int(10) unsigned NOT NULL,
KEY `id_articles` (`id_articles`,`id_users`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
It is correct but you will want to add separte indexes on id_articles and id_users (also you might want to name the columns 'id_article' and 'id_user' for sanity).
CREATE TABLE IF NOT EXISTS `article_likes` (
`id_article` int(10) unsigned NOT NULL,
`id_user` int(10) unsigned NOT NULL,
KEY `id_article` (`id_article`),
KEY `id_user` (`id_user`)
) ENGINE=InnoDB;
The reason you want separate indexes is because in mysql if you create an index on columns (A, B) that index will be used in queries having in the where clause column A, or columns A and B.
In your case for example if you made a query "SELECT * FROM article_likes WHERE id_user=X" this query would not use an index.
An ever better option would be to add a combined index and a separate index on the second column from the combined index. Like this:
CREATE TABLE IF NOT EXISTS `article_likes` (
`id_article` int(10) unsigned NOT NULL,
`id_user` int(10) unsigned NOT NULL,
KEY `id_article_user` (`id_article`, `id_user`),
KEY `id_user` (`id_user`)
) ENGINE=InnoDB;
This way you would have optimal performance on queries like 'WHERE id_user=X', "WHERE id_article=X', "WHERE id_article=X AND id_user=Y"
This is a valid way Chris. You can use COUNT() to match the id_articles in the articles_likes table against the current article you are viewing in articles.
$articles_id = 23;
mysql_query("SELECT COUNT(*) FROM articles_likes
WHERE id_articles = ".$articles_id);
You can also just leave COUNT() (MySQL) out and instantly know which users are the "likers" of the articles and use count() (PHP) on the returned Array to duplicate the effect of COUNT() in MySQL.
i would have a total of 3 tables. an articles table, and the user id could be a column in that for users who submit articles , but you need a separate user table since not all users will submit articles (i am assuming), and then a 3rd table for likes, that takes the primary key from users and the primary key from articles and uses them as foreign keys. so each time an article is liked, an entry is made in the 3rd table

Mysql error with converting from myISAM to innodb

hey guys, i'm getting this error.
Error 1452 : Cannot add or update a child row: a foreign key constraint fails (`s2794971db/ProfileInterests`, CONSTRAINT `ProfileInterests_ibfk_2` FOREIGN KEY (`InterestID`) REFERENCES `Interests` (`ID`))
I change my tables from myISAM to innodb...found out I needed to so that delete was easier.
I had issues with it so I deleted the table which I needed to create the relationships with.
Then I made it again
I originally had
create table if not exists Users (
ID int not null auto_increment primary key,
FirstName varchar(40) not null,
LastName varchar(40) not null,
UserName varchar(40) not null,
UserEmail varchar(40) not null,
UserDOB timestamp not null,
UserJoin datetime not null
);
create table if not exists Interests(
ID int not null auto_increment primary key,
Interests varchar(40) not null
);
create table if not exists ProfileInterests (
userID int not null References Users(ID),
InterestID int not null References Interests(ID),
MiddleID int not null auto_increment primary key
);
but then I deleted the last table and made it
create table if not exists ProfileInterests (
userID int not null,
InterestID int not null,
MiddleID int not null auto_increment primary key
);
and then I made userID and InterestID into index's and then I added a relation User-> ID for userID and interests->ID for interestID
the error occurs when i'm trying to input data into via a php form.
Any ideas...really need some help!
Obviously, you're trying to insert a record into ProfileInterests for which there is no matching record in the Interests table. Look at the exact insert query, and check that you're supplying a valid value for every field in the table which is part of a foreign key relationship.

is_unique syntax in mysql?

I have a table entity called position. I am storing the value using smallint(2) datatype, where I intend to store the value from 0 to 9 (max). I want to make sure the value is just a single integer and an integer should not be repeated at any cost. There should be a unique value assigned to each id of the position entity in the table ranging from 0 to 9. How do I achieve it? Is there any mysql syntax for that?
I am using MySQL with PHP.
here is the mysql table could someone add me the unique code and show
CREATE TABLE `advertisements` (
`id` int(11) NOT NULL auto_increment,
`title` varchar(255) NOT NULL,
`position` smallint(2) NOT NULL,
`active` tinyint(1) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
is this the correct syntax?
CREATE TABLE `advertisements` (
`id` int(11) NOT NULL auto_increment,
`title` varchar(255) NOT NULL,
`position` smallint(2) NOT NULL UNIQUE,
`active` tinyint(1) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
You must define that column as UNIQUE.
ALTER TABLE `a` ADD UNIQUE (
`id`
)
Your question has two parts:
How do I ensure that a value is unique in a column?
Add a unique index.
How do I restrict a value to be in the range 0 to 9?
You can add a foreign key constraint to a table that lists the allowed values.
First of all, smallint(2) and smallint(1234) and smallint are exactly the same in MySQL. The numeric argument is not a limit on the length or the range of values, it's only a hint for display width. MySQL's smallint is a 16-bit integer, with a range from -32768 to 32767. smallint unsigned has a range from 0 to 65535.
You can ensure no duplicates exist in a column by declaring a PRIMARY KEY or a UNIQUE KEY:
CREATE TABLE MyTable (
position SMALLINT NOT NULL,
UNIQUE KEY (position)
);
To restrict the values to the range 0 to 9, there are a few options:
Write a trigger that causes an error if you try to store a value outside the range.
DELIMITER //
CREATE TRIGGER ZeroToNine BEFORE INSERT ON MyTable
FOR EACH ROW
BEGIN
DECLARE p SMALLINT;
IF (NEW.position NOT BETWEEN 0 AND 9) THEN
SET p = 'Position must be between 0 and 9';
END IF;
END //
DELIMITER ;
Use a foreign key constraint so the column references a table that you populate with the values 0 to 9.
CREATE TABLE ZeroToNine (
position SMALLINT NOT NULL PRIMARY KEY
) ENGINE=InnoDB;
INSERT INTO ZeroToNine VALUES (0), (1), (2), (3), (4), (5), (6), (7), (8), (9);
CREATE TABLE MyTable (
position SMALLINT NOT NULL,
UNIQUE KEY (position),
FOREIGN KEY (position) REFERENCES ZeroToNine (position)
) ENGINE=InnoDB;
Other databases also support a CHECK constraint, but MySQL unfortunately doesn't support this feature.
CREATE TABLE MyTable (
position SMALLINT NOT NULL
CHECK (position BETWEEN 0 AND 9),
UNIQUE KEY (position)
);

Categories