Correct way for joining Tables - sql

I have a table let's say products like this:
Id
Description
Category_Id
Location_Id
Seller
what is the correct way of storing the id of category and location? I was told by a programmer that i have to make a table let's say tblChoices like this:
Id
Code
Value
and to use as value of code 'category' for categories and value of code 'location' for locations. then store the description in the value field.
Is this the correct approach or is it better to use a table for category, and a different table for location? How the 2 ways affect speed of retrieving data? the one way surely has less tables but uses the same table many times with joins to retrieve data

The general approach is to use a different table for categories and for locations.
Why? You can declare foreign key relationships, which in turn help you maintain data integrity.
There are some situations where you might want to store all reference tables in a single table -- for instance, it can be easier to translate the database into another language.
In general, though, you want separate reference tables. After all, you might have additional columns such as categories.long_term or locations.country.

Related

Multiple record types and how to split them amongst tables

I'm working on a database structure and trying to imagine the best way to split up a host of related records into tables. Records all have the same base type they inherit from, but each then expands on it for their particular use.
These 4 properties are present for every type.
id, name, groupid, userid
Here are the types that expand off those 4 properties.
"Static": value
"Increment": currentValue, maxValue, overMaxAllowed, underNegativeAllowed
"Target": targetValue, result, lastResult
What I tried initially was to create a "records" table with the 4 base properties in it. I then created 3 other tables named "records_static/increment/target", each with their specific properties as columns. I then forged relationships between a "rowID" column in each of these secondary tables with the main table's "id".
Populating the tables with dummy data, I am now having some major problems attempting to extract the data with a query. The only parameter is the userid, beyond that what I need is a table with all of the columns and data associated with the userid.
I am unsure if I should abandon that table design, or if I just am going about the query incorrectly.
I hope I explained that well enough, please let me know if you need additional detail.
Make the design as simple as possible.
First I'd try a single table that contains all attributes that might apply to a record. Irrelevant attributes can be null. You can enforce null values for a specific type with a check constraint.
If that doesn't work out, you can create three tables for each record type, without a common table.
If that doesn't work out, you can create a base table with 1:1 extension tables. Be aware that querying that is much harder, requiring join for every operation:
select *
from fruit f
left join
apple a
on a.fruit_id = f.id
left join
pear p
on p.fruit_id = f.id
left join
...
The more complex the design, the more room for an inconsistent database state. The second option you could have a pear and an apple with the same id. In the third option you can have missing rows in either the base or the extension table. Or the tables can contradict each other, for example a base row saying "pear" with an extension row in the Apple table. I fully trust end users to find a way to get that into your database :)
Throw out the complex design and start with the simplest one. Your first attempt was not a failure: you now know the cost of adding relations between tables. Which can look deceptively trivial (or even "right") at design time.
This is a typical "object-oriented to relational" mapping problem. You can find books about this. Also a lot of google hits like
http://www.ibm.com/developerworks/library/ws-mapping-to-rdb/
The easiest for you to implement is to have one table containing all columns necessary to store all your types. Make sure you define them as nullable. Only the common columns can be not null if necessary.
Just because object share some of the same properties does not mean you need to have one table for both objects. That leads to unnecessary right outer joins that have a 1 to 1 relationship which is not what I think of as good database design.
but...
If you want to continue in your fashion I think all you need is a primary key in the table with common columns "id, name, groupid, userid" (I assume ID) then that would be the foreign key to your table with currentValue, maxValue, overMaxAllowed, underNegativeAllowed

Table referenced by other tables having different PKs

I would like to create a table called "NOTES". I was thinking this table would contain a "table_name" VARCHAR(100) which indicates what table put in the note, a "key" or multiple "key" columns representing the primary key values of the table that this note applies to and a "note" field VARCHAR(MAX). When other tables use this table they would supply THEIR primary key(s) and their "table_name" and get all the notes associated with the primary key(s) they supplied. The problem is that other tables might have 1, 2 or more PKs so I am looking for ideas on how I can design this...
What you're suggesting sounds a little convoluted to me. I would suggest something like this.
Notes
------
Id - PK
NoteTypeId - FK to NoteTypes.Id
NoteContent
NoteTypes
----------
Id - PK
Description - This could replace the "table_name" column you suggested
SomeOtherTable
--------------
Id - PK
...
Other Columns
...
NoteId - FK to Notes.Id
This would allow you to keep your data better normalized, but still get the relationships between data that you want. Note that this assumes a 1:1 relationship between rows in your other tables and Notes. If that relationship will be many to one, you'll need a cross table.
Have a look at this thread about database normalization
What is Normalisation (or Normalization)?
Additionally, you can check this resource to learn more about foreign keys
http://www.w3schools.com/sql/sql_foreignkey.asp
Instead of putting the other table name's and primary key's in this table, have the primary key of the NOTES table be NoteId. Create an FK in each other table that will make a note, and store the corresponding NoteId's in the other tables. Then you can simply join on NoteId from all of these other tables to the NOTES table.
As I understand your problem, you're attempting to "abstract" the auditing of multiple tables in a way that you might abstract a class in OOP.
While it's a great OOP design principle, it falls flat in databases for multiple reasons. Perhaps the largest single reason is that if you cannot envision it, neither will someone (even you) looking at it later have an easy time reassembling the data. Smaller that that though, is that while you tend to think of a table as a container and thus similar to an object, in reality they are implemented instances of this hypothetical container you are trying to put together and operate better if you treat them as such. By creating an audit table specific to a table or a subset of tables that share structural similarity and data similarity, you increase the performance of your database and you won't run in to strange trigger or select related issues later.
And you can't envision it not because you're not good at what you're doing, but rather, the structure is not conducive to database logging.
Instead, I would recommend that you create separate logging tables that manage the auditing of each table you want to audit or log. In fact, some fast google searches show many scripts already written to do much of this tasking for you: Example of one such search
You should create these individual tables and then if you want to be able to report on multiple table or even all tables at once, you can create a stored procedure (if you want to make queries based on criterion) or a view with an included SELECT statement that JOINs and/or UNIONs the tables you are interested in - in a fashion that makes sense to the report type. You'll still have to write new objects in to the view, but even with your original table design, you'd have to account for that.

Store forum subcategories in the same table or in a separate table

I'd like to hear opinions on if it is better to keep forum categories and subcategories in the same table or in two separate tables...
Let's say you have a table ForumCategories. By adding a colum ParentId referencing the PK Id in the same table you could easily keep both the main categories and subcategories in the same table.
Alternatively, you could create a separate table ForumSubCategories and make the Id on that table a FK referencing PK Id column of the ForumCategories table.
Both solutions would work but what are the pros and cons of each solution?
Obviously, this is a more generic question that can apply to many other scenarios I just couldn't come up with a better phrasing in a hurry...
I can't think of any benefits of using 2 tables. Using 2 tables is going to constrain you to a 2 level tree. If you look at things as objects, then subcategories really are just category object. So put them in the same table. The 1 table structure will be simpler to design around and develop queries for.
If you know for sure that your forums will have only 2 levels of categories, then having 2 tables is reasonable.
Though storing categories in one table with foreign key to itself, basically, allows you store a tree of categories with virutally unlimited levels.
If they are the same entity (Category), you can link to itself. The parent would have a null for the parent ID or it could be linked to itself. This limits you to only one level unless you have a second table to handle the many-to-many possible relationships.
They must have the same fields or you're going to have unecessary fields for one or the other type. A separate table is why you would do this because they're not the same.
This is typical for an employee table. The supervisor is another employee record.

Possible to have a table with variable columns?

It might be a stupid question, but here goes:
Is it possible to make a dynamic table that's able to contain rows with variable number of columns and custom column names?
I have glanced over EAV-modelling, but it seems heavy. A real life example could be this:
Let's say I have a register with customers. But each customer might have different information to be entered. And depending on what you want to enter, it should be reflected in the database. (I.E. every customer has different columns)
Is this impossible/probable?
Update:
The standard approach (i.e. having a table with all needed columns and saving information only into columns that make sense for a particular customer while setting the remaining ones to NULL) doesn't work for me because what I want can't use 'fixed' column names. Example one customer might want CVR-number and another might want their phonenumber as a reference number. And a third might want some completely different information. So to avoid having a table containing 500 columns, I have now thought of making an extra table containing rows of column-data. Like so: Id, Name, Value, CustomerId. So when I want information for a customer, all I have to do is to iterate through this table with a specific customer Id.
my own edit!:
Sorry for troubling you with this simple SQL-issue! :-) Have a nice day...
You could model this as a one-to-many relationship between a Customer and a CustomerAttributes table. Something like:
**Customer table**
CustomerId
LastName
FirstName
...
**CustomerAttributes table**
CustomerId
AttributeName
AttributeValue
This is not possible in Sql-Server. As Marco says, you can store each customer's data in xml.
If all the columns are known ahead of time and some customers use one set and other customers use a different set, then sub-tables with each set of columns is the normal approach.
If the columns are not known ahead of time, then how would the data even be used? No code or reports could refer to it. Perhaps it should be stored unstructured in a general purpose 'Notes' field.
As far as I know it's not possible in standard relational databases, but you can take a look at schema-less databases called 'No-SQL' like MongoDB

Difference between a db view and a lookuptable

When I create a view I can base it on multiple columns from different tables.
When I want to create a lookup table I need information from one table, for example the foreign key of an order table, to get customer details from another table. I can create a view having parameters to make sure it will get all data that I need. I could also - from what I have been reading - make a lookup table. What is the difference in this case and when should I choose for a lookup table?? I hope this ain't a bad question, I'm not very into db's yet ;).
Creating a view gives you a "live" representation of the data as it is at the time of querying. This comes at the cost of higher load on the server, because it has to determine the values for every query.
This can be expensive, depending on table sizes, database implementations and the complexity of the view definition.
A lookup table on the other hand is usually filled "manually", i. e. not every query against it will cause an expensive operation to fetch values from multiple tables. Instead your program has to take care of updating the lookup table should the underlying data change.
Usually lookup tables lend themselves to things that change seldomly, but are read often. Views on the other hand - while more expensive to execute - are more current.
I think your usage of "Lookup Table" is slightly awry. In normal parlance a lookup table is a code or reference data table. It might consist of a CODE and a DESCRIPTION or a code expansion. The purpose of such tables is to provide a lsit of permitted values for restricted columns, things like CUSTOMER_TYPE or PRIORITY_CODE. This category of table is often referred to as "standing data" because it changes very rarely if at all. The value of defining this data in Lookup tables is that they can be used in foreign keys and to populate Dropdowns and Lists Of Values.
What you are describing is a slightly different scenario:
I need information from one table, for
example the foreign key of an order
table, to get customer details from
another table
Both these tables are application data tables. Customer and Order records are dynamic. Now it is obviously valid to retrieve additional data from the Customer table to display along side the Order data, and in that sense Customer is a "lookup table". More pertinently it is the parent table of Order, because it has the primary key referenced by the foreign key on Order.
By all means build a view to capture the joining logic between Order and Customer. Such views can be quite helpful when building an application that uses the same joined tables in several places.
Here's an example of a lookup table. We have a system that tracks Jurors, one of the tables is JurorStatus. This table contains all the valid StatusCodes for Jurors:
Code: Value
WS : Will Serve
PP : Postponed
EM : Excuse Military
IF : Ineligible Felon
This is a lookup table for the valid codes.
A view is like a query.
Read this tutorial and you may find helpful info when a lookup table is needed:
SQL: Creating a Lookup Table
Just learn to write sql queries to get exactly what you need. No need to create a view! Views are not good to use in many instances, especially if you start to base them on other views, when they will kill performance. Do not use views just as a shorthand for query writing.