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
Related
I'm working in a web page with PHP and MySQL where I have this DB:
CREATE TABLE action (
idaction INT NOT NULL AUTO_INCREMENT,
--Other columns
PRIMARY KEY (`idaction`));
CREATE event (
idevent INT NOT NULL AUTO_INCREMENT,
--Other columns
PRIMARY KEY (`idevent`));
CREATE TABLE currentGame (
user_email VARCHAR(45) NOT NULL,
--Other columns
PRIMARY KEY (`user_email`));
CREATE TABLE IF NOT EXISTS currentEvents (
currentGame_user_email VARCHAR(45) NOT NULL,
event_idevent INT NOT NULL,
PRIMARY KEY (currentGame_user_email, event_idevent),
FOREIGN KEY (currentGame_user_email) REFERENCES currentGame (user_email),
FOREIGN KEY (event_idevent) REFERENCES event (idevent));
CREATE TABLE IF NOT EXISTS spawnConditions (
action_idaction INT NOT NULL,
event_idevent INT NOT NULL,
PRIMARY KEY (action_idaction, event_idevent),
FOREIGN KEY (action_idaction) REFERENCES action (idaction),
FOREIGN KEY (event_idevent) REFERENCES event (idevent));
So I need to do a query which has the actions which fulfill any of these conditions:
It is not in spawnConditions.
If it is in spawnConditions, all the events which it is related to in this table, must be in the subgroup of currentEvent with a certain known user_email.
In other words, for action A1, being in spawnConditions with events E1 and E2, to be able to be selected from table action, both E1 and E2 must be in currentEvents with the known currentGame_user_email.
Can it be written using only SQL or do I need to involve PHP?
I think that not exists can get the work done here. Basically, you want to filter out actions for which a corresponding record exists in currentEvents with a currentGame_user_email other than a fixed value:
select a.*
from action a
where not exists (
select 1
from spawnConditions sc
inner join currentEvents ce
on ce.event_idevent = sc.event_idevent
where
sc.action_idaction = a.idaction
and ce.currentGame_user_email <> ?
)
The question mark represents the "certain known user_email" you mentioned in the question.
I'm trying to think of an SQL statement I can write up in MySQL in which I can get all the tracks included inside an album. The way I have it set up is Album_id which is the primary key to my album table is linked inside the tracks table in the form of a foreign key. That way each track row is linked to an album in the album table.
I'll further detail below the layout of my tables:
tbl_Albums
As you can see I have the Album_id as the primary key and it's auto_incremented so the id will automatically update when a new row is entered.
CREATE TABLE `tbl_Albums` (
`Album_id` int(11) NOT NULL auto_increment,
`Album_Name` varchar(32) NOT NULL,
`Number_Of_Tracks` int(11) NOT NULL,
`Genre` varchar(32) NOT NULL,
`Artist_id` int(11) NOT NULL,
PRIMARY KEY (`Album_id`),
KEY `Artist_id` (`Artist_id`),
CONSTRAINT `tbl_Albums_ibfk_2`
FOREIGN KEY (`Artist_id`) REFERENCES `tbl_Artist` (`Artist_id`))
tbl_Tracks
Inside the tracks table I set a foreign key with album_id, so I link the tracks to a specific album.
CREATE TABLE `tbl_Tracks` (
`Track_id` int(11) NOT NULL auto_increment,
`Track_Name` varchar(32) NOT NULL,
`Length` time NOT NULL,
`Artist_id` int(11) NOT NULL,
`Album_id` int(11) NOT NULL,
PRIMARY KEY (`Track_id`),
KEY `Artist_id` (`Artist_id`),
KEY `Album_id` (`Album_id`),
CONSTRAINT `tbl_Tracks_ibfk_1`
FOREIGN KEY (`Artist_id`) REFERENCES `tbl_Artist` (`Artist_id`),
CONSTRAINT `tbl_Tracks_ibfk_2`
FOREIGN KEY (`Album_id`) REFERENCES `tbl_Albums` (`Album_id`))
I have the tables linked properly, but I'm trying to think of an MySQL statement that can allow me to show all the tracks linked to a specific album and have come up empty so far. I'm then trying to implement the code into a php form for a user to use to list out the tracks
Any help would be greatly appreciated.
SELECT tbl_Albums.Album_id, tbl_Albums.Album_Name, tbl_Tracks.Track_id, tbl_Tracks.Track_Name, tbl_Tracks.Album_id
FROM tbl_Albums
INNER JOIN tbl_Tracks ON tbl_Albums.Album_id = tbl_Tracks.Album_id WHERE
`tbl_Albums`.`Album_Name`='Your album name'
ORDER BY
`tbl_Tracks`.`Track_id`;
SELECT
`t2`.*
FROM
`tbl_Albums` `t1`
INNER JOIN
`tbl_Tracks` `t2`
ON
`t2`.`Album_id`=`t1`.`Album_id`
WHERE
`t1`.`Album_Name`='Name of Your album'
ORDER BY
`t2`.`Track_id`;
I don't know if I understand your question correct, but a simple select should do the trick?
If you know the album id, for instance 5:
SELECT * FROM `tbl_Tracks` WHERE `Album_id` = 5;
If you know the album name:
SELECT `t`.* FROM `tbl_Tracks` AS `t`
LEFT JOIN `tbl_Albums` AS `a` ON `a`.`Album_id` = `t`.`Album_id`
WHERE `a`.`Album_Name` = 'Thriller';
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.
I try to insert Data in the temporary Table, but when i call select last_insert_id() it return allways the same number. I have set the autoincement setting.
In the normal Table works, but when i Copy the normal Table to a temporary Table, then i have the problem with the select last_insert_id().
This is my code:
CREATE TEMPORARY TABLE IF NOT EXISTS suchergebnisse_temp (SELECT * from suchergebnisse);
INSERT INTO suchergebnisse_temp SET datensatzid='2865', datum='2015-05-13 00:00:00', tabelle='task', sortierung1='1';
SELECT LAST_INSERT_ID();
The Normal Table:
CREATE TABLE IF NOT EXISTS `suchergebnisse` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`tabelle` varchar(100) NOT NULL DEFAULT '0',
`datensatzid` bigint(20) NOT NULL DEFAULT '0',
`datum` datetime NOT NULL,
`sortierung1` int(11) NOT NULL COMMENT 'Priorität',
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Temporäre Tabelle.';
Can you help me? Thanks :)
I forgot to add the key explicit to the temporary Table. It needs to execute the following code:
ALTER TABLE `suchergebnisse_temp`
CHANGE COLUMN `id` `id` BIGINT(20) NOT NULL AUTO_INCREMENT FIRST,
ADD PRIMARY KEY (`id`);
Because with:
CREATE TEMPORARY TABLE IF NOT EXISTS suchergebnisse_temp (SELECT * from suchergebnisse);
copys only the Field Data but not the Key Data. The Key Data must be declared separately.
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)