Two image tables or one for storing default images? - mysql

I currently maintain a single DB table that has some info for images that are stored in a file system. This setup works well with the several hundred thousand photos I currently have recorded.
For a users default image I maintain a separate folder that contains the photo but this has become a maintenance nightmare. Should I create a second table that stores a reference to the default photo from table 1 or is it better to add a new field in table 1 that's a boolean I can set to indicate a default photo?
My table looks something like this:
image_table
id user_id file_name
1 6 xvy.jpeg
2 6 abc.jpeg
3 6 def.jpeg
Proposed solution:
image_table
id user_id file_name default
1 6 xvy.jpeg 0
2 6 abc.jpeg 1
3 6 def.jpeg 0
In this proposed solution it seems as though I would need to make two SQL calls to reset the default and then a second call to set a new default photo if a user changes it...

It is better to add new fields instead of add new tables, if the second table would have identical columns to the first if you went that approach.
Reasoning: If I need to get values from both tables, I would need to do a cumbersome UNION. What if you had three or more tables that all had the same kind of data, and I wanted all of them at once? It just gets clunkier and clunkier and more awkward to code against.

Well i can see you are using some SQL database but dont take me wrong why dont you try a NoSQL database such as MongoDB . I know creating a field as a flag or creating a new table doesnt seems to be a good design.

Related

database model: group similar images together

I've created a db in mySQL that stores many things, but specially images. The table name for storing the images is image, like so:
image (image_id, title, caption, filename, published_date, ...)
It's been almost 2 years and i've uploaded almost 5000 images into the table.
Now, i want to add a new functionality. I want to group similar images so when im looking at an image, i can also have the option to look at images that are similar.
I'm not sure if i need a new table or should i use the same table or both. Any ideas/suggestions on how it should be?
You should create another table with that similiarities.
Why can't it be the same table ? One record in You table can have many similiar records (so it will be adding many columns to that table or for every similiarity there will be another row in YOur table. So the only logical option is to create another table.
IdFromMainTable | IdOfSimiliarRecord
Later on You can show that similiarites in a view easily joining that table by IdFromMainTable. Or both IdOfSimiliarRecord and IdFromMainTable. [depends if u want to add 2 records for similiar records or just one for similiar pair]
It sounds like what you want to do is create tags for the images. There are a number of ways to do that, but adding the tags to the same table would prevent a whole lot of joins from taking place and would likely be faster. You could just store the tags as JSON (if you're using MySQL =>7.5.8).

Storing list of users associated with a certain item

This is a bit hard to explain.
But i have built an app where users create what i like to call 'raffles' and then users subscribe to it.
I have a table for the raffles, and i could have a column of type text in it and store all the users in it separated by commas(,)
or i could create a separate table where users are added and associated to the raffle via another field called 'raffle_id' or something like it.
I'm not sure how effective both of these methods will be efficient in the long run or for scaling.
Some advise would be appreciated.
I would recommend against storing your user information in CSV format. The main reason for this is that CSV will make querying the table by user difficult. It will also make doing updates difficult. SQL databases were designed to handle relational data using tables. So in your case I would design the raffles table to look like thia:
raffles (raffle_id, user_id)
And the data might look like this:
1 1
1 3
1 7
2 1
2 2
2 3
2 6
In other words, each record corresponds to a single raffle-user relation. Assuming that you only have a few dozen users and raffles happen every so often, thia should scale fine. And if this raffles table ever gets too large at a much later date you can archive a portion of it.
See [What is the best way to add users to multiple groups in a database?][1]
Raffles are the "Groups". "UserInGroup" becomes UserInRaffle, your join table.

Database Architecture for logging

This is something that has bothered me for a long time and i still have been unable to find an answer.
I have a huge system with alot of different features. What is common for this system is of course that my users can
create, update, read & delete
different parts of my system.
For simple reasons lets say i have an application that has the following features:
Document administration
Video administration
User administration
Salery administration
(Please do note i took these at random just to prove a point that all of these would have their own separate tables and does not necessarily be connected).
Now i wish to create some sort of logging system. So that when ever someone either create,update or delete an entity it will be recorded.
Now as far as i can see i can do this two ways.
1.
Create a logging table for each of the 4 features that is in my system. However with this method i am required to create a logging table for each new feature i add to the system. i would also have to combine data from X number of tables if i wish to create a log which potentially could be a huge task!
2.
i could create something like the following:
However once again i would have to add a col for each new feature i will add.
So my question is what is the best way for creating logging database architecture
Or is there an easier way?
Instead of one target_xx for each feature, you could do it this way:
target_id | target_type
1 video
4 document
5 user
2 user
or even better. A table with target types and insert only the respective id's on target_type
Something like this:
if you want to capture for each table creation and update date, i would just use the default and the update event from mysql. You can define the fields like this for a table:
ALTER TABLE table
ADD COLUMN CreateDate Datetime DEFAULT CURRENT_TIMESTAMP,
ADD COLUMN LastModifiedDate Datetime ON UPDATE CURRENT_TIMESTAMP;
You can add these 2 fields in all tables. If you want to use one central table for logging (which might be more difficult to manage, because you always need to create joins, maybe also worse performance), then I would work with triggers.

Dilemma about the number of columns on a table

Scenario:
I am creating a website for a checklist, it can be done/accessed by multiple users in the same time thus it needs certain fields to be editable, saveable and retrievable.
Dilemma:
The checklist has 212 entries, this means 212 rows. I have 5 columns that needs entries thus, 212x5. This means, I have to create 1060 columns to be able for me to code the website to do what I want it to do. 1060 columns on a table seems wrong and very tiring to use.
My Sample solution:
I would divide the 5 columns into 5 tables, making the date that the checklist was created as their primary key. I would then use this 5 tables for their corresponding columns thus reducing the number of columns per table to 212.
Is there anyway that I could reduce this? Sorry for the long post, any help would be appreciated.
**Edit: For some reason, I can't comment on any answers, says error on page. Nevertheless, I do appreciate everybody's answer; Yet I have 1 info that may change your answers. I have thought of making 5 columns instead of the obnoxious 1060, but doing that, I would need/The system would need to create 1 table per 1 worksheet and of course, over time, this would cause massive problems to the database.
Although still pretty huge, ah_hau's answer seems to be the smallest and easiest to handle. By using it, the system would create 217 entries per checklist, but will use 6-8 columns only. Thank you to everyone who shed light into this dillemma, I do hope that I see you guys again on my next question. Cheers!
There are different ways to do it, I'd just store a Json string per checklist. The Json string would be a Json array of object { checklistName, checklistValue, timestamp }. So, the database table would only have two columns { id, checklist }. This is on the minimum side, you might want to break it down to smaller Json objects and/or add more details to them.
looking thrrough all your requirements, thou you've ban the common 6 column setup, I'd still suggest you to use a similar setup.
try to have a table like this
id [bigInt] (PK,auto_incrment)
rowId [int] //checklist row id
columnId [int] //checklist column id
text [varchar/text]
create_date [Date]
create_time [Time]
Index
unique key chekcklist_cell (create_date, rowId, columnId)
depending on your preference, you could also split columnId field into 5 columns with name column1~5 to reduce the DB entry count. But i'd suggest using my setup as it seems like user will update your checklist 1 cell at a time (or multiple cell all around the list), which my schema will make more sense. Also this schema is very expandable and could easily add new fields to them. Last thing I could think of is that you doesn't have to lock the whole checklist while a user is only updating 1 cell. This helps speed up that concurrent access thing.
why not directly add 1 more column in your checklist table?
your table structure should look like
userid
entryid (value from 1-212)
col1_entry
col2_entry
col3_entry
col4_entry
col5_entry

What is the right way of building user favourites table (Performance)

I guess that title isn't very descriptive, so I will explain! I have table called users_favs where is stored all info about which posts user has liked, which post he has favourited and the same for comments. info there is stored as serealized array / or JSON who cares.
Question: What is better? Stay like this or to make 4 tables for each of the fields and store not in serealized version but like user_id => post_id???
What I think about second option is that after some time this field will be GIGANTIC. Also, I will need to make 4 queries (or with JOINS) to take all of the info from these tables.
Keeping it in 1 table means that you'll only need 1 table access and 0 joins to get all the data. While storing it in 4 tables, you'll need at least 1 table access and n-1 joins, when you need n fields of information. Your result set at the end of the query will probably be the same, so the amount of data send over the network is independent of your table structure.
I presume a scenario when you will have data for fav_categories and other columns are null. Similarly for columns fav_posts, liked_posts, liked_comments. So there is a high probability that in each row , only three columns will have data most of the time (id,user_id,any one of rest). If my assumptions are right and the use cases as well , then i would definitely go four four tables.
To add to above you can always choose from whether you want to make read-friendly or write-friendly.