I'm making a web app where users are posting their articles and other users can read them.
I wanna have a function in there where users can either save the articles that they like og remove those they don't wanna see anymore.
How should i set up my mysql tabels for that?
i'm thinking to have these tabels.
TABELS:
- articles
- users
- liked
- removed
I hope it makes sense?
You could probably build something similar to this:
Here is the SQL script to generate these tables:
-- tables
-- Table ArticleTypes
CREATE TABLE ArticleTypes (
ArticleTypeId int NOT NULL ,
ArticleTypeDesc varchar(255) NOT NULL ,
CONSTRAINT ArticleTypes_pk PRIMARY KEY (ArticleTypeId)
);
-- Table Articles
CREATE TABLE Articles (
ArticleId int NOT NULL ,
ArticleName varchar(255) NOT NULL ,
ArticleDescription varchar(255) NOT NULL ,
ArticleTypeId int NOT NULL ,
CONSTRAINT Articles_pk PRIMARY KEY (ArticleId)
);
-- Table BookmarkStatus
CREATE TABLE BookmarkStatus (
BookmarkStatusId int NOT NULL ,
BookmarkStatusDesc varchar(255) NOT NULL ,
CONSTRAINT BookmarkStatus_pk PRIMARY KEY (BookmarkStatusId)
);
-- Table Bookmarks
CREATE TABLE Bookmarks (
BookmarkId int NOT NULL ,
UserId int NOT NULL ,
ArticleId int NOT NULL ,
BookmarkStatusId int NOT NULL ,
CONSTRAINT Bookmarks_pk PRIMARY KEY (BookmarkId)
);
-- Table Users
CREATE TABLE Users (
UserId int NOT NULL ,
UserName varchar(255) NOT NULL ,
UserStatus int NOT NULL ,
CONSTRAINT Users_pk PRIMARY KEY (UserId)
);
-- foreign keys
-- Reference: Articles_ArticleTypes (table: Articles)
ALTER TABLE Articles
ADD CONSTRAINT Articles_ArticleTypes
FOREIGN KEY Articles_ArticleTypes (ArticleTypeId)
REFERENCES ArticleTypes (ArticleTypeId);
-- Reference: Bookmarks_Articles (table: Bookmarks)
ALTER TABLE Bookmarks
ADD CONSTRAINT Bookmarks_Articles
FOREIGN KEY Bookmarks_Articles (ArticleId)
REFERENCES Articles (ArticleId);
-- Reference: Bookmarks_BookmarkStatus (table: Bookmarks)
ALTER TABLE Bookmarks
ADD CONSTRAINT Bookmarks_BookmarkStatus
FOREIGN KEY Bookmarks_BookmarkStatus (BookmarkStatusId)
REFERENCES BookmarkStatus (BookmarkStatusId);
-- Reference: Bookmarks_Users (table: Bookmarks)
ALTER TABLE Bookmarks
ADD CONSTRAINT Bookmarks_Users
FOREIGN KEY Bookmarks_Users (UserId)
REFERENCES Users (UserId);
Basically, you can design your Bookmarks table to determine if the article is Active or Deleted based on the BookMarkStatusId (for e.g. 1 for Active, 2 for Deleted). Your bookmarks table will handle the relationship between users and articles tables.
Hope this helps!
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.
Good evening,
following table situation:
create table TableA (
pkA int not null auto_increment,
propertyA varchar(20),
primary key (pkA) );
create table TableB (
pkB int not null auto_increment,
pkA int not null,
propertyB varchar(20),
primary key (pkB),
foreign key (pkA) references TableA (pkA) on delete cascade);
create table TableC (
pkC int not null auto_increment,
pkB int not null,
propertyC varchar(20),
primary key (pkC),
foreign key (pkB) references TableB (pkB) on delete cascade );
When I delete a row from parent table 'TableA' I need to know which rows (primary keys) got deleted in 'TableB' and 'TableC' as well.
I am working with PHP 7.0. I was hoping there is something like mysqli_insert_id for deletes, but... nada :(
Any ideas?
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 have a MySQL database with several tables, connected with linking tables. My problem was that DELETE statements were very complicated. So in an attempt to make them simpler I tried setting up foreign keys with cascade deletes.
Here is my table structure
--------------
-n_size_class-
--------------
-s_id -
-s_name -
--------------
-------------
-n_size_rows-
-------------
-sr_id -
-sr_name -
-sr_value -
-------------
----------------
-n_size_columns-
----------------
-sc_id -
-sc_name -
-sc_value -
----------------
-----------------
-n_size_row_link-
-----------------
-srl_id -
-srl_size -
-srl_row -
-----------------
-----------------
-n_size_col_link-
-----------------
-scl_id -
-scl_size -
-scl_col -
-----------------
The idea is that the n_size_class table is the primary object (a size class) and then the rows and columns are children of the size class. The linking tables are then used to tie rows and columns to the size class. Previously, my inserts worked fine and deletes were a problem. Now that I tried setting up delete cascades, my inserts are broken (but my deletes work fine). My goal is to make inserts work properly, where size_class is inserted, then for each row, it is inserted into size_row and then also inserted into size_row_link, and the same for columns. Then when you delete just the size_class, all links and rows and columns are deleted as well.
What is the proper way to foreign key/cascade these tables? Right now, I get a foreign key constraint error when I try to insert anything into the columns or row table.
As per request, the create statements:
CREATE TABLE `n_size_class` (
`s_id` int(11) NOT NULL auto_increment,
`s_name` text NOT NULL,
PRIMARY KEY (`s_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;
CREATE TABLE `n_size_columns` (
`sc_id` int(11) NOT NULL auto_increment,
`sc_name` text NOT NULL,
`sc_value` text NOT NULL,
PRIMARY KEY (`sc_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;
CREATE TABLE `n_size_rows` (
`sr_id` int(11) NOT NULL auto_increment,
`sr_name` text NOT NULL,
`sr_value` text NOT NULL,
PRIMARY KEY (`sr_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;
CREATE TABLE `n_size_row_link` (
`srl_id` int(11) NOT NULL auto_increment,
`srl_size` int(11) NOT NULL,
`srl_row` int(11) NOT NULL,
PRIMARY KEY (`srl_id`),
KEY `srl_row` (`srl_row`),
KEY `srl_size` (`srl_size`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;
CREATE TABLE `n_size_col_link` (
`scl_id` int(11) NOT NULL auto_increment,
`scl_size` int(11) NOT NULL,
`scl_col` int(11) NOT NULL,
PRIMARY KEY (`scl_id`),
KEY `scl_col` (`scl_col`),
KEY `scl_size` (`scl_size`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;
The way I see it you have 3 objects in play: Sizes, Rows, and Columns.
I'm assuming:
That the linking tables are because a Size can be assigned to many Rows/Columns, and Rows/Columns can have many Sizes.
That when a Size is deleted the assignments should be deleted, no the Rows/Columns themselves.
That when a Row/Column is deleted the assignments should be deleted, not the Sizes themselves.
So:
CREATE TABLE sizes (
size_id INTEGER UNSIGNED AUTO_INCREMENT,
size_name VARCHAR(255),
...
PRIMARY KEY(size_id)
);
CREATE TABLE rows (
row_id INTEGER UNSIGNED AUTO_INCREMENT,
...
PRIMARY KEY(row_id)
);
CREATE TABLE columns (
col_id INTEGER UNSIGNED AUTO_INCREMENT,
...
PRIMARY KEY(col_id)
);
CREATE TABLE l_row_size (
row_id INTEGER UNSIGNED,
size_id INTEGER UNSIGNED,
PRIMARY KEY(row_id, size_id),
CONSTRAINT FOREIGN KEY l_row_size-row_id (row_id) REFERENCES rows (row_id) ON UPDATE CASCADE ON DELETE CASCADE,
CONSTRAINT FOREIGN KEY l_row_size-size_id (size_id) REFERENCES sizes (size_id) ON UPDATE CASCADE ON DELETE CASCADE
);
CREATE TABLE l_col_size (
col_id INTEGER UNSIGNED,
size_id INTEGER UNSIGNED,
PRIMARY KEY(col_id, size_id),
CONSTRAINT FOREIGN KEY l_col_size-row_id (col_id) REFERENCES rows (col_id) ON UPDATE CASCADE ON DELETE CASCADE,
CONSTRAINT FOREIGN KEY l_col_size-size_id (size_id) REFERENCES sizes (size_id) ON UPDATE CASCADE ON DELETE CASCADE
);
Then:
foreach( $sizes as $size ) {
$dbh->query("INSERT INTO sizes (size_name) VALUES ('{$size['name']}')");
$size_id = $dbh->last_insert_id();
foreach( $rows as $row ) {
$dbh->query("INSERT INTO l_row_size (size_id, row_id) VALUES ($size_id, {$row['id']})");
}
foreach( $cols as $col ) {
$dbh->query("INSERT INTO l_col_size (size_id, col_id) VALUES ($size_id, {$col['id']})");
}
}
edit
Sharf commented:
Each Size Class can have many rows and many columns, but each row and column can only belong to one size class.
Well then you only need 3 tables:
CREATE TABLE sizes (
size_id INTEGER UNSIGNED AUTO_INCREMENT,
...
PRIMARY KEY(size_id)
);
CREATE TABLE rows (
row_id INTEGER UNSIGNED AUTO_INCREMENT,
size_id INTEGER UNSIGNED,
...
PRIMARY KEY(row_id)
CONSTRAINT FOREIGN KEY rows-size_id (size_id) REFERENCES sizes (size_id) ON UPDATE CASCADE ON DELETE CASCADE,
);
CREATE TABLE columns (
col_id INTEGER UNSIGNED AUTO_INCREMENT,
size_id INTEGER UNSIGNED,
...
PRIMARY KEY(col_id),
CONSTRAINT FOREIGN KEY cols-size_id (size_id) REFERENCES sizes (size_id) ON UPDATE CASCADE ON DELETE CASCADE,
);
Linking tables are only truly useful in the case of n:m relationships, and this is a case of two 1:n relationships. Each Row/Column object need only store a reference to the Size to which they belong.
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.