Abstract table design question - mysql

I am working on one document system and got some logic/architectual problems. In this system will be many types of documents - incoming, outgoing, etc. Every document type have its own number of cols whitch must be filled. On the paper all is easy, but in software - I need some advice :)
For example:
incoming document type 1 have 16 cols,
outgoing document type 1 have 15cols,
inner document have 9 cols,
etc...
At first I thought, that I will make one table, named "Categories" where will be stored (in tree) document types (incoming, outgoing, etc) and one generic table "Documents" with maximum of possible rows (for example 25) where would be stored all documents and if not used some cell, then ignored it.
After I thougth that I can make a much simpler - for every type of document - own table, but after some thinking is seemed to be worst solution.
So I want the best possible solution for this.
Maybe you can help me?
Thanks!

This is a typical example for table inheritance. You'd do something like this:
Document
----------
DocumentId (PK)
DocumentType
... any columns common to the different formats
DocumentIncoming
----------
DocumentId (PK, FK to Document)
... columns specific to Incoming
DocumentOutgoing
----------
DocumentId (PK, FK to Document)
... columns specific to Outgoing

Use a central "Documents" table that contains a category code and only those columns that apply to every single category.
Then, for each category use a table that links back to the appropriate record in Documents and "adds" the additional columns appropriate for that category.

Related

How to build database for variant management in a webshop

I am searching for a guideline on how to set up my database for a auction side.
My problem is, that there is a lot of different product types - let's say paintings, clothes, computers etc. They have different specifications, and it should be possible to set just Product A in size L on auction - or the whole stock of Product B e.g.
How should I build my database for optimal performance - and coding - in this case?
I would suggest the following database/object structure:
[Auction] n..1 [Category] 1..n [Variation Attribute] 1..n [Attribute Value]
An auction then has a category and several attribute values referring the variation attribute as well:
[Auction] = [Category], [Name], [Description]
[Auction_AttrVal] = [AuctionID], [VarAttrID], [AttrValID]
First of all you can have some kind of category table, which holds items like "Paintings", "Clothes", "Computers". An auction / product is assigned to one category.
Each category then defines variation attributes for this specific category. An example would be "Size" for the category "Clothes" or "CPU" for the category "Computers". You can also add predefined values for the variation attributes to limit the number of variations and avoid differentiations like "3GhZ" vs "3 GhZ".
This mechanism also allows for easy filtering of search results. You select a category and simply load all variation attributes as filters (or add a flag to an attribute to declare it as such) and offer the values for filtering to the end-user.
Furthermore you can make variation attributes for a category mandatory to force users who create the auctions (I'm assuming it's Consumer-to-Consumer) to provide sufficient information for their auction.
The code will probably be quite generic and simple. The database structure is highly flexible and extensible. Performance is much better than having all in one table. You probably should create an index (for the field AuctionID) for the Auction_AttrVal table. Please let me know if the database structure is not explained properly.

How to structure table Activities in a database?

I have a site written in cakephp with a mysql database.
Into my site I want to track the activities of every users, for example (like this site) if a user insert a product I want to put this activity into my database.
I have 2 ways:
1) One table called Activities with:
- id
- user_id
- title
- text
- type (the type of activity: comment, post edit)
2) more table differenced by activities
- table activities_comment
- table activities_post
- table activities_badges
The problem is when I go to the page activities of a user I can have different type of activities and I don't know which of this solution is better because a comment has a title and a comment, a post has only a text, a badge has an external id to its table (for example) ecc...
Help me please
I'm not familiar with CakePHP, but from purely database perspective your data model should probably look similar to this:
The symbol denotes category (aka. inheritance, subclass, subtype, generalization hierarchy etc.). Take a look at "Subtype Relationships" in ERwin Methods Guide for more info.
There are generally 3 strategies for implementing the category:
All types in single table. This requires a lot of NULLs and requires CHECKs to make sure separate subtypes are not inappropriately "intermingled".
All concrete types in separate tables (excluding the base, which is ACTIVITY in your case), which means common fields and relationships must be repeated in all child tables.
All types in separate tables (including the base). This implementation requires a little more JOINing, but is flexible and clean. It should be your default, unless there are strong reasons against it.

Mysql Database Layout

I have created the following database layout, and started coding the application. The more I read, the more I realize my database layout is probably incorrect / inefficient / a bad idea. Before I develop too much code using this layout, I want to make sure I am doing it "correctly".
Basically I have a list of ~2000 stores, and a list of ~50 promotional codes. I need to store whether or not each code is valid at each store. Right now I chose to store each store number as a column header, with the first column containing all of the different possible codes. Here's an image of part of the table so far (1 represents the code being valid, 0 invalid at that store).
The promotional codes will change relatively frequently, but the store numbers should be relatively static, and not change very much.
This is my first time creating a database from scratch like this, and I am a beginner at using mysql, so any help is much appreciated!
You should better use a table for your stores. If you don't, when one store will be added you'll spend a lot of time to add a new field...
Here is what I would do:
table store will contains your 2000s stores
id
name
table code will contains your 50 codes
id
name
table code_store will contains only the valid codes ID, and related store_id(no need to save invalid ones I guess)
code_id
store_id
This type of relation is called many-to-many. I typically have three table for this type of situation. One table for the stores, one for the promo codes, and a third relational table that would have two columns: the store id and the promo id.

MySQL table with multiple values in one field [duplicate]

This question already has answers here:
Is storing a delimited list in a database column really that bad?
(10 answers)
Closed 4 years ago.
I'm building a database for a real estate company.. Those real estate properties are managed by the sales people using a CodeIgniter website.
How should I proceed with the database design for this table. The fields like address/location, price etc. are pretty straightforward but there are some sections like Kitchen Appliences, Property Usage etc... where the sales people can check multiple values for that field.
Furthermore, a property can have multiple people attached to it (from the table people), this can be an intermediaire, owner, seller, property lawyer etc... Should I use one field for this or just I create an extra table and normalize the bindings?
Is the best way to proceed just using one field and using serialized data or is there a better way for this?
In a relational database you should never, EVER, put more than one value in a single field - this violates first normal form.
With the sections like Kitchen Appliances, Property Usage etc... where the sales people can check multiple values for that field, it depends on whether it will always be the same set of multiple options that can be specified:
If there are always the same set of multiple options, you could include a boolean column on the property table for each of the options.
If there are likely to be a variety of different options applicable to different properties, it makes more sense to set up a separate table to hold the available options, and a link table to hold which options apply to which properties.
The first approach is simpler and can be expected to perform faster, while the latter approach is more flexible.
A similar consideration applies to the people associated with each house; however, given that a single property can have (for example) more than one owner, the second approach seems like the only one viable. I therefore suggest separate tables to hold people details (name, phone number, etc) and people roles (such as owner, seller, etc.) and a link table to link roles to properties and people.
You should create extra table for it....
For example...
Consider the scenario that 1 item may have many categories and 1 category may have many items...
Then you can create table like this...
Create three tables for that....
(1) tblItem :
fields:
itemId (PK)
itemName
etc..
(2) tblCategory :
fields:
categoryId (PK)
categoryName
etc..
(3) tblItemCategory :
fields:
itemId (PK/FK)
categoryId (PK/FK)
So according to your data you can create an extra table for it....
I think it would be optimize way....
If you want your data to be in third normal form, then you should think in terms of adding extra tables, rather than encoding multiple values into various fields. However it depends how far your brief goes.

The best way to structure this database?

At the moment I'm doing this:
gems(id, name, colour, level, effects, source)
id is the primary key and is not auto-increment.
A typical row of data would look like this:
id => 40153
name => Veiled Ametrine
colour => Orange
level => 80
effects => +12 sp, +10 hit
source => Ametrine
(Some of you gamers might see what I'm doing here :) )
But I realise this could be sorted a lot better. I have studied database relationships and secondary keys in my A-Level computing class but never got as far as to set one up properly. I just need help with how this database should be organised, like what tables should have what data with what secondary and foreign keys?
I was thinking maybe 3 tables: gem, effects, source. Which then have relationships to each other?
Can anyone shed some light on this? Is a complex way like I'm proposing really the way to go or should I just carry on with what I'm doing?
Cheers.
I happen to be passingly familiar with the environment you're describing (:))
Despite what you have convinced yourself, what you are doing is not particularly complex.
Anyway, currently, you have a table with no relationships. It's simple. It's easy. Each gem exists in the database.
If you were to move to the three tables that you proposed, you would also need to include link tables to assemble the tables into useable data, especially since (and mind, I'm not quite sure how your distinctions boil out) the effects and source table are involved in a many-to-x relationship: each gem has up to two effects, and each effect has up to Y gems where it is present // each source has up to Z gems.
I'd stick with the single table. The individual records may be longer, but its much simpler, and you'll encounter fewer errors than if you were trying to establish linking tables or the like.
Questions to ask yourself:
Is there a 1 to 1 relationship between gem, effects, and source?
Would you more often be pulling effects without pulling data from gem?
If the proposed tables have a 1 to 1 relationship then I'd suggest leaving them combined in one table. The only time I would consider splitting them out in this condition is if I only needed data from effects without needing other data AND these tables were going to be large enough to justify having them stored on different drives. Otherwise, you're just making work for yourself, adding more storage requriements and reaping exactly zero benefits.
You should also consider whether you will need the effects information for actual usage, or display only. If it is display only, no big deal to have it in one column in a table. If you have to use it, for example to apply the +12 and +10 appropriately, then I think you should put each occurrence of it in a separate column. Accordingly, you should have a separate table for effects, and then a separate table storing which gems have which effects, maybe gemeffects. The Effects table might have better descriptions of what "sp" stands for, maybe the min and max ranges, etc. The GemEffects table would just have the gem id, the value, and the effect itself. For example
Effects
effect => hit
desc => How many hit points
minimum => 0
maximum => 100
GemEffects
id => 40153
effect => sp
value => 12
and
id => 40153
effect => hit
value => 10
You would answer your own question if you do a simple exercise: describe in a natural, descriptive language your system. Which entities, their attributes, how they interact with other entities, etc. Underline substantives and verbs. Ask what entities do you mean to manage (eg: will there be an interface to manage the "effects" table?) You'll be surprised how it all gets assembled naturally.
Now for your example, I'd suggest two approaches (without syntactic details)
1) to gain experience in relational design, with some complexity overhead, and granular over each entity
gem (id, name,color_id,source_id,effect_assoc_id)
color (id, name)
source (id, name)
effect (id,value,nature_id)
nature (id, name)
effect_assoc (id, gem_id, effect_id)
2) straight to the point, possibly valid depending on the cardinality of your relations
just carry on ;)
From your description, I'd go with #1.
I would recommend the following:
Move all effects into their own table (e.g., ID, Name, Description, Enabled, ...)
Move source into its own table (e.g., ID, Name, Description, Enabled, ...)
Drop gems "effects" column (migrates to step 5 below)
Convert the gems "source" column into a foreign key value that corresponds to the PK from the "source" table
Add a new table to link a single gem entity to zero or more effect entities
Example: tbl_GemsEffectsLink, with two columns named "GemID" and "EffectID," that by
themselves are foreign keys back to the entity tables and when taken together, make up the
composite primary key.
A sample view of this link table would be as follows:
GemID EffectID
1 1
1 2
2 1
2 2
2 3
So, in summary, you would have the following tables:
gems
effects
source
gemseffectslink
With each table having the following columns:
gems
id (PK)
name
colour
level
sourceid (FK)
effects
id (PK)
name
description
enabled
...
source
id (PK)
name
description
enabled
...
gemseffectslink
gemid (FK)
effectid (FK)
Lastly, this assume each gem can have zero or more effects, a single source (you can enforce NULL or NOT NULL for this gem.sourceid FK field), and that the level integer value is just that (i.e., not representing something more robust and exhaustive in that there exists some type of "Level" entity and the value of "80" in your sample data row uniquely identifies one of these "Level" entities).
Hope this helps!
Michael