table creating regarding social networking post - mysql

I want to design structure for posting image,video,url, audio,text etc for users.
I have create
CREATE TABLE users (
userID INT NOT NULL AUTO_INCREMENT,
firstName VARCHAR(50),
lastName VARCHAR(50),
password CHAR(32),
PRIMARY KEY (userID)
);
CREATE TABLE post(
postID INT NOT NULL AUTO_INCREMENT,
message VARCHAR(200)
PRIMARY KEY (postID));
MY question is should I design different tables for storing image,video,url etc
like
Image table
CREATE TABLE post_image(
imageID INT NOT NULL AUTO_INCREMENT,
imgPATH VARCHAR(200)
PRIMARY KEY (imageID));
same of video,link etc.
Or it can be done only in single table.

I've seen this done two ways.
You create a generic "asset" table that stores all possible things that could be attached to a post. Videos, images, URLs, etc.
Create a separate table for each asset type. A post_image table, post_comment, post_video, etc.
I prefer (2) only because the asset types will be pretty different from each other. Think of storing information about a video. You have the video duration, whether or not to auto-play, etc. Images will never have those properties.
So even though you could put all those things into one table, I would strongly recommend not to do it.

Related

How can i join another table with the primary of the other

I am creating an application like trello for that i am using MySQL as an database till now i have created authentication system using MySQL and express,node js now i want to create table for cards to save the data so, i want to know how can i link the users data to the users name.
I have created a table users with the following field id(primary key, auto_increment),name,email,password
now i want to create a table card in which the users card would be present so how can i link user table column correspond to the particular
use, thanks in advance really new to backed
Maybe this lines of code can help you out a little. To get a better grasp of the topic.
-- This statement creates the cards table you may want to use (alternatively see Barmars Comment, this maybe a more professional solution)
CREATE TABLE Cards (
id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
customer_id INT,
firstname VARCHAR(30) NOT NULL,
lastname VARCHAR(30) NOT NULL,
email VARCHAR(50)
)
-- This statement then "connects" the tables. It makes the customer_id in the cards table a foreign key of the primary key of the customers table.
FOREIGN KEY (customer_id) REFERENCES customers(customer_id)
After implementing this you can use JOIN in your queries to query multiple tables.
If you want more info, this video can help you understand the topic:
https://www.youtube.com/watch?v=USaXlErI-QE

Array association and DB design

I'm trying to create a shopping cart sort of DB, where users can checkout certain items and I would be able to see what items each person has and I would also be able to see who a specific item is checked out to.
I would also like to have an image for each item. (not sure how efficient that is?)
Currently I have something like this:
CREATE TABLE person(
id CHAR(9) NOT NULL PRIMARY KEY,
name VARCHAR(30) NOT NULL
);
CREATE TABLE items(
id CHAR(9) NOT NULL PRIMARY KEY,
itemName VARCHAR(30) NOT NULL,
category VARCHAR(30) NOT NULL,
subcategory VARCHAR(30) NOT NULL,
image LONGBLOB
);
CREATE TABLE person_items(
personID CHAR(9) NOT NULL,
itemID CHAR(9) NOT NULL,
FOREIGN KEY (personID) REFERENCES person(id),
FOREIGN KEY (itemID) REFERENCES items(id)
);
Is this an efficient way to basically store an array of items that a person is allowed to check out, or are there better ways?
Also, is storing a LONGBLOB for an image a good idea or is there a better way to do that?
First of all your IDs in your tables should be INTEGERs. The relation table 'person_items' enables a n:m relation between person and items, which should be your goal, if I understood your question.
I suggest to save a path and the image file name in your db, so that you can get this value and use it as link or something similar in your app. I would not save the image as a blob cause you have a lot of unneccesary work with headers and so on. And if using a path in the db, you will easily be able to use different file formats. Just my opinion.

MySQL table (re)design

We have "user" and "study" entities in our application, stored in their respective tables.
A study represents a kind of research and the data that has been gathered.
They have a many-to-many relationship, so we need a linking table: studies_users.
We assign roles to users. There are a few "normal" roles, which are study-dependent, so for the same user they can be different, depending on the chosen study. This means that those kind of roles would have to be stored as part of the studies_users table.
There is however a request for a new, "special" role, lets call it superadmin, which basically means the user has all possible roles (or rights) in all kinds of studies. That means such property wouldn't have to be stored in the studies_users linking table, it's sufficient to store it in the users table in a new column (is_superadmin for example), since it applies to all of the studies.
However, if I store it separately from other roles (in the users table), it seems to be somewhat illogical and can lead to unwanted complexity in the code that handles related logic.
Should I store such attribute in the linking table or in the users table? Why?
some very basic SQL for the tables:
CREATE TABLE `users` (
`ID` int(10) unsigned NOT NULL AUTO_INCREMENT,
`EMAIL` varchar(100),
PRIMARY KEY (`ID`)
);
CREATE TABLE `studies` (
`ID` int(10) unsigned NOT NULL AUTO_INCREMENT,
`NAME` varchar(150),
PRIMARY KEY (`ID`)
);
CREATE TABLE `studies_users` (
`ID` int(10) unsigned NOT NULL AUTO_INCREMENT,
`STUDY_ID` int(10),
`USER_ID` int(10),
`ROLE_ID` tinyint(3),
PRIMARY KEY (`ID`)
);
If you stick your DB design to the real world, 'superadmin' is an attribute of the user, functionally determined by the user only, and as such should be in table user. Yes, this will add some complexity to the queries but will spare you headaches when users change from superadmin to 'normal'; you will just need to change a flag and your data will remain consistent at all times.
Since your "superadmin" role is a special role, not like the other roles you describe, you shouldn't feel compelled to store them together in the same table. You may call them both roles but that doesn't mean they're the same thing.
The most straightforward approach would be to have a table storing the primary keys of all users who belong to this superadmin role. Adding a field to the user table means storing additional data (or even worse, NULLs) in every row, even when only a very small minority of your users are superadmins.

MySQL table design - refer to multiple foreign rows

Minimilized background (ie in bare pseudo code details)
I am making a record keeping (among other things) php/mysql app for my farm. There are lots of types of animals etc that could have pictures (or other records - videos etc.) but just for simplicity I'll only refer to one of each (Goats and Pictures). so say the
tables are approximately like so:
CREATE TABLE BMD_farmrecords_goats (
goat_id INT NOT NULL AUTO_INCREMENT,
goat_name TEXT,
...more columns but whatever, unimportant...
primary_key(goat_id))
CREATE TABLE BMD_farmrecords_pictures (
media_id INT NOT NULL AUTO_INCREMENT,
media_name TEXT,
media_description TEXT,
media_description_short TEXT,
media_date_upload DATE,
media_date_taken DATE,
media_uploader INT, //foreign key constrained to user table but unimportant for question
media_type ENUM('jpg','gif','png'),
media_hidden BOOL,
media_category INT, //foreign key constrained to category table but unimportant for question
PRIMARY KEY (media_id)
So the problem(s):
Obviously a picture could have multiple goats in it so I can't just
have one foreign key in picture to refer to goat.
there are more than one livestock tables that would also make that a poor choice but not worried about that right now
Basically no optimization has been applied as of yet (ie no lengths set, using TEXT rather than varchar(length)) etc; I'm not worried about that until I populate it a bunch and see exactly how long I want everything.
so the question:
what is the best_ way to link a picture to multiple goats (in terms of A) best performance B) best code conformance to standards. I'm thinking I'll have to do an extra table:
create TABLE BMD_farmrecords_goatpictures (
id INT NOT NULL AUTO_INCREMENT
picture_id INT //foreign key to BMD_farmrecords_pictures->media_id
goat_id INT//foreign key to BMD_farmrecords_goats->goat_id
So is there any better way to do that?
Of course with that method I'll probably have to change *_goats table to be a parent *_animals table with then a type field and reference animal_id instead but I'm not worried about that, just about whether or not the extra table referencing both tables is the best method.
thanks;
From the discussion just changing my original idea to use a composite primary key:
create TABLE BMD_farmrecords_goatpictures (
picture_id INT //foreign key to BMD_farmrecords_pictures->media_id
goat_id INT//foreign key to BMD_farmrecords_goats->goat_id
PRIMARY KEY (picture_id, goat_id))

How would I create this MySQL Schema?

Suppose I have a blog post entity.
It has many attributes
It has comments attached to it.
It has many states (deleted/locked/invisible, etc).
It has many "tags". (keywords, school_id, user_id)
Obviously, comments should be its own table, with a many-to-one relationship to Blog table.
But what about "states" or "tags"? Would you put that in another table? Or would you stick that in many columns?
What about attributes...if they get too big? Because as my website grows, the blog post will have more and more attributes attached (title, author, blah, blah....). What happens if the attribute list goes as high as 100?
Here's a sample:
Again.. It's just a sample.. There are other approaches that you can use.
Here we go:
-- basic-basic blog
CREATE TABLE blog_entry (
blog_entry_id INT NOT NULL AUTO_INCREMENT,
blog_entry_title VARCHAR(255) NOT NULL,
blog_entry_text VARCHAR(4000) NOT NULL,
create_date DATETIME,
state_id INT
);
-- create a look-up table for your blog entry's state
CREATE TABLE be_state (
state_id INT NOT NULL AUTO_INCREMENT,
name CHAR(30) NOT NULL,
PRIMARY KEY (state_id)
);
-- create a look-up table for your blog entry's tag/s
CREATE TABLE be_tag (
tag_id INT NOT NULL AUTO_INCREMENT,
name CHAR(30) NOT NULL,
PRIMARY KEY (tag_id)
);
-- a table to store multiple tags to one entry
CREATE TABLE blog_entry_tags (
blog_entry_id INT NOT NULL,
tag_id INT NOT NULL,
PRIMARY KEY (blog_entry_id, tag_id)
);
-- a table to store definitions of attributes
CREATE TABLE be_attribute (
attribute_id INT NOT NULL AUTO_INCREMENT,
name CHAR(30)
);
-- now have a table to which you can assign multiple attributes to one blog
-- of course, this is if I understand you correctly
-- where you want to have additional attributes
-- aside from the basic properties of a blog entry
-- and will allow you, if you choose to do it
-- to not necessarily have all attributes for each entry
CREATE TABLE blog_entry_attributes (
blog_entry_id INT NOT NULL,
attribute_id INT NOT NULL,
PRIMARY KEY (blog_entry_id, attribute_id)
-- PK enforces one blog entry may have only one attribute of its type
-- meaning, no multiple attributes of 'location' attribute,
-- for example, for one blog. Unless of course you wrote half the entry
-- in one location and finished it in the next.. then you should
-- NOT enforce this primary key
);
blog_entry - your main table, where the goods go
be_state - define them here, and insert their state_id values in blog_entry.state_id
be_tag - have multiple tags like we do here
blog_entry_tags - since you can possibly have many tags for one blog entry, store them here and insert blog_entry.blog_entry_id and the corresponding be_tag.tag_id together. one tag of its type per blog entry. meaning you can't tag entry#1 (for example) the tag php twice or more.
be_attribute - store attribute definitions here like location, author, etc
blog_entry_attributes - similar to blog_entry_tags where you can assign one or more than one be_attribute to a blog entry.
Again, this is just one approach.
first of all, states should be a tightly structured thing, so you should create separate columns for them. Think about what you need at the beginning, but you can easily add one or two more columns later.
Tags like keywords shouldn't be stored in columns, because the amount is growing rapidly over time. That wouldn't make any sense. So for that, build a table with id and keyword in it and a link table with post_id and keyword_id. You could also omit the keyword_id and directly link post_id and keyword.
Make sure that both columns combined define the primary key, so you can not end up with a keyword stored several time to one particular post.
For attributes it can be the same. It is not a bad practice to create an attribute table with attribute_id, attribute_name and maybe more information and a link table attribute_id and post_id and content.
You can also easily enhance it to be multilingual by using attribute_ids.
Comments are the same, stored in a separate table with a link to a user and a post: comment_id, user_id, post_id, content and maybe parent_id, which can be a comment_id if you want comments to be commentable again.
That's it for a brief overview.