Database hierarchy, aggregation, relations in LibreOffice Base - database

I am working on a homework project where we design a website for a store, and I have been assigned the database. This is my first database attempt. I am using LibreOffice Base for the design, and cannot find any guides on how to make subtypes. For example, for every shirt in the inventory, there'd be a different group of colors it comes in and for every different color a list of individual sizes and how many of each size is in stock. However, I can't find aggregation anywhere in "Table Relations."
So I make a table for shirts with the base information (brand, price, etc), and then a separate table with just 2 columns (size and number of units in stock --- we're letting the possibility of multiple colors wait for now). I then make a form for the shirt with the base information and a subform with 2 columns: size and number available. Both of the forms are tables rather than labeled text boxes. However, the subform for shirt size does not maintain separate information for each row in the main form (ie the one with the base information for the shirts). How the heck do I do this?
Lastly, since this is my first crack at databases, I would not be at all surprised if I'm going at it all wrong, and if so would gladly appreciate a push in the right direction or a webpage explaining how to do this that I didn't find due to not entering the correct search terms.

You need to create linked fields in the master table. The shirt table has a primary key; refer to that in the subordinate table. Alternatively, create a primary key in the subordinate table and refer to it in the master table. Then in the subform --> properties, designate the appropriate link between the master and slave fields. The functionality is described in the LibreOffice Base handbook (p.105)

Related

Database Architecture: Multiple Type Relations

I'm building a Laravel application that has "listings". These listings can be things like boats, planes, and automobiles; each with their own specific fields.
I will also have an images table that should relate to each type of listing and a users table that needs to map to each type of listing. I'm trying to determine the best way to map each listing type back to images and users.
One way I've thought of doing this was having separate boats, planes and automobiles tables with their specific fields and then having specific boat_images plane_images and automobile_images tables to map to each respective type. But then relating each type to a user would be a bit tricky.
I don't think one giant listing table with all fields I'd ever use through these 3 (which could grow in size later) would make sense --- and I also don't believe having a general metadata field that has a JSON object full of specifications for each listing would work well either when I want to have a searchable database.
I know of pivot tables, but I'm trying to grasp the overall architecture here. Any help would be greatly appreciated. Thanks!
You could have a listings table, holding only id and name. Boats, planes, automobiles and others should be a subset table.
Each table will have its own entity. And the Listing entity will have multiple hasMany relationships with its subset tables. These relationships will be named like boats(), planes(), etc. Each subset listing entity will hold a single belongsTo relationship.
Using these subset tables should also help to compartmentalize form validation.
You can have a single images table and use a polymorphic relationship towards the listings table. This one is a huge savior.

MS Access Database Confused

I am setting up a database for our hunting club, plus learning access along the way...ouch
I want the database to contain all of the deer observed along with their locations, when the user enters the data it will go as buck/doe/fawn/unknown and they will also enter the location where the deer was observed. The location could be a stand located at various different places on the property or a stand could be located on a food plot.
Here is where I am confused, I got to this point and really just don't know the best path to follow. I have followed much of the normalization techniques and set up relationships. I am working with a form (frmEnterNewStand) to add the stands to the database, what I need is a single combo box with choices that come from two tables (tblProperty Sections for stands not located on food plots) and (tblFoodplots for stands located on food plots). But couldn't figure that one out. So I attempted to add food plots as another entry but things started getting messy.
Since I am new to this I don't even know the right questions to ask, but I just cannot figure out the best way to organize this to be able to enter data easily then access the data easily.
I know we will want to perform queries to get statistics on, i.e. how many deer were observed blah blah blah, we will also want to query the food plots as well, how many deer were seen on food plot 1 for example, and what time of day. We will also keep up with other food plot parameters.
I have been taking the Udemy course and have several books, but my mind is blown, any help would be appreciated.
I am going to include an example map of our property, the blue numbers are different sections for the property (tblPropertySections), the yellow S numbers are Stand 1, 2 etc, the orange F numbers are Food Plot 1, 2 etc.
Also included are my current screenshots of what I have so far. I was going to try to post images but I need at least 10 reputation points i guess.
NOt sure what else I need to provide but I will say thank you in advance
tim
thank you
tim
I think you should start simple on this and add complexity as needed.
From my reading of the problem the main outcome is a database that records deer sightings. The easiest possible "database" is just a table that lists the sighting, and associated info.
For example:
ID, Date, Time, DeerType, Location, SeenBy, Comments
1, 1/1/2015, 11:45pm, "Doe", "Behind the shed", "Garry Abblet", "After a few beers Garry went for a slash and saw a deer"
Start with that and then worry about what needs to be added. I know a single table isn't the most exciting database to learn about, but you should follow a philosophy of the simplest solution usually being the best.
Access forms are essentially the visual representation of tables. In fact, if users were just computers you would not need a user interface but can manage processing (edit, add, save, delete) through code. The combo box form control is the tool needed to select corresponding data from other tables, specifically foreign keys.
As you point out, a Stand can either be on a Property Section or Food Plot. So in the tblStands table you can carry two foreign keys: Property Section ID and Food Plot ID.
Then, on their corresponding forms of tblStands the IDs wold be stored/bounded in combo boxes whose RowSources are a queries of the underlying tables:
SELECT id, PropertySectionName FROM tblPropertySections
SELECT id, FoodPlotName FROM tblFoodPlots
Now, computers would know which ID to pick but not humans who would need names/titles to help identify which item to select. Fortunately, combo boxes come with a special hidden column feature where the IDs can be hidden from view but its related name is presented on the form. However, the ID is stored in table. You set this up with the wizard when you select and position combo boxes.
Manually, or no-wizard approach, you do the following in Property Sheet of selected combo box:
Format tab
Column Count: 2 (or any greater than 2 depending on RowSource query)
Column Width: 0"; 1" (or any non-zero that fits into combo box's width)
Data tab
Control Source: PropertySheetID (or FoodPlotID)
Row Source: (see above queries)
Row Source type: table/query
Bound column: 1
Altogether, users will navigate to frmEnterNewStand and choose if the Stand is on Property Section or Food Plot by entering one combo box and not the other (leave label instructions as needed, since users are human).

Best approach to avoid Too many columns and complexity in database design

Inventory Items :
Paper Size
-----
A0
A1
A2
etc
Paper Weight
------------
80gsm
150gsm etc
Paper mode
----------
Colour
Bw
Paper type
-----------
glass
silk
normal
Tabdividers and tabdivider Type
--------
Binding and Binding Types
--
Laminate and laminate Types
--
Such Inventory items and these all needs to be stored in invoice table
How do you store them in Database using proper RDBMS.
As per my opinion for each list a master table and retrieval with JOINS. However this may be a little bit complex adding too many tables into the database.
This normalisation is having bit of problem when storing all this information against a Invoice. This is causing too many columns in invoice table.
Other way putting all of them into a one table with more columns and then each row will be a combination of them.. (hacking algorithm 4 list with 4 items over 24 records which will have reference ID).
Which one do you think the best and why!!
Your initial idea is correct. And anyone claiming that four tables is "a little bit complex" and/or "too many tables" shouldn't be doing database work. This is what RDBMS's are designed (and tuned) to do.
Each of these 4 items is an individual property of something so they can't simply be put, as is, into a table that merges them. As you had thought, you start with:
PaperSize
PaperWeight
PaperMode
PaperType
These are lookup tables and hence should have non-auto-incrementing ID fields.
These will be used as Foreign Key fields for the main paper-based entities.
Or if they can only exist in certain combinations, then there would need to be a relationship table to capture/manage what those valid combinations are. But those four paper "properties" would still be separate tables that Foreign Key to the relationship table. Some people would put an separate ID field on that relationship table to uniquely identify the combination via a single value. Personally, I wouldn't do that unless there was a technical requirement such as Replication (or some other process/feature) that required that each table had a single-field key. Instead, I would just make the PK out of the four ID fields that point to those paper "property" lookup tables. Then those four fields would still go into any paper-based entities. At that point the main paper entity tables would look about the same as they would if there wasn't the relationship table, the difference being that instead of having 4 FKs of a single ID field each, one to each of the paper "property" tables, there would be a single FK of 4 ID fields pointing back to the PK of the relationship table.
Why not jam everything into a single table? Because:
It defeats the purpose of using a Relational Database Management System to flatten out the data into a non-relational structure.
It is harder to grow that structure over time
It makes finding all paper entities of a particular property clunkier
It makes finding all paper entities of a particular property slower / less efficient
maybe other reasons?
EDIT:
Regarding the new info (e.g. Invoice Table, etc) that wasn't in the question when I was writing the above, that should be abstracted via a Product/Inventory table that would capture these combinations. That is what I was referring to as the main paper entities. The Invoice table would simply refer to a ProductID/InventoryID (just as an example) and the Product/Inventory table would have these paper property IDs. I don't see why these properties would be in an Invoice table.
EDIT2:
Regarding the IDs of the "property" lookup tables, one reason that they should not be auto-incrementing is that their values should be taken from Enums in the app layer. These lookup tables are just a means of providing a "data dictionary" so that the database layer can have insight into what these values mean.

Database design for a product aggregator

I'm trying to design a database for a product aggregator. Each product has information about where it comes from, what it costs, what type of thing it is, price, color, etc. Users need to able to search and filter results based on any of those product categories. I also expect to have a large number of users. My initial thought was having one big table with every product in it with a column for each piece of information and an index on anything I need to be able to search by but I think this might be inefficient with a lot of users pounding on this one table. My other thought was to organize the database to promote a tree-like navigation of tables but because you can search by anything I'm not sure how I would organize the tables.
Any thoughts on some good practices?
One table of products - databases are designed to have lots of users pounding on tables.
(from the comments)
You need to model your data. This comes from looking at the all the data you have, determining what is related to what (a table is called a relation because all the attributes in a row are related to a candidate key). You haven't really given enough information about the scope of what data (unstructured?) you have on these products and how it varies. Are you going to have difficulties because Shoes have brand, model, size and color, but Desks only have brand, model and finish? All this is going to inform your data model. Typically you have one products table, and other things link to it.
Some of those attributes will be foreign keys to lookup tables, others (price) would be simple scalars. Appropriate indexing and you'll be fine. For advanced analytics, consider a dimensionally modeled star-schema, but perhaps not for your live transaction system - depends what your data flow/workflow/transactions are. Or consider some benefits of its principles in your transactional database. Ralph Kimball is source of good information on dimensional modeling.
I dont see any need for the tree structure here. You can do with single table.
if you insist on tree structure with hierarchy here is an example to get you started.
For text based search, and ease of startup & design, I strongly recommend Apache SOLR. The SOLR API is easy to use (especially JSON). Databases do text search poorly, and I would instead recommend that you just make sure that they respond to primary/unique key queries properly, and those are the fields you should index.
One table for the products, and another table for the product category hierarchy (you don't specifically say you have this but "tree-like navigation of tables" makes me think you might).
I can see you might be concerned about over-indexing causing problems if you plan to index almost every column. In that case, it might be best to index on the top 5 or 10 columns you think users are likely to search for, unless it's possible for a user to search on ANY column. In that case you might want to look at building a data warehouse. Maybe you'll want to look into data cubes to see if those will help...?
For hierarchical data, you need a PRODUCT_CATEGORY table looking something like this:
ID
PARENT_ID
NAME
Some sample data:
ID PARENT_ID NAME
1 ROOT
2 1 SOCKS
3 1 HELICOPTER PARTS
4 2 ARGYLE
Some SQL engines (such as Oracle) allow you to write recursive queries to traverse the hierarchy in a single query. In this example, the root of the tree has a PARENT_ID of NULL, but if you don't want this column to be nullable, I've also seen -1 used for the same purposes.

Do 1 to 1 relations on db tables smell?

I have a table that has a bunch of fields. The fields can be broken into logical groups - like a job's project manager info. The groupings themselves aren't really entity candidates as they don't and shouldn't have their own PKs.
For now, to group them, the fields have prefixes (PmFirstName for example) but I'm considering breaking them out into multiple tables with 1:1 relations on the main table.
Is there anything I should watch out for when I do this? Is this just a poor choice?
I can see that maybe my queries will get more complicated with all the extra joins but that can be mitigated with views right? If we're talking about a table with less than 100k records is this going to have a noticeable effect on performance?
Edit: I'll justify the non-entity candidate thoughts a little further. This information is entered by our user base. They don't know/care about each other. So its possible that the same user will submit the same "projectManager name" or whatever which, at this point, wouldn't be violating any constraint. Its for us to determine later on down the pipeline if we wanna correlate entries from separate users. If I were to give these things their own key they would grow at the same rate the main table grows - since they are essentially part of the same entity. At no pt is a user picking from a list of available "project managers".
So, given the above, I don't think they are entities. But maybe not - if you have further thoughts please post.
I don't usually use 1 to 1 relations unless there is a specific performance reason for it. For example storing an infrequently used large text or BLOB type field in a separate table.
I would suspect that there is something else going on here though. In the example you give - PmFirstName - it seems like maybe there should be a single pm_id relating to a "ProjectManagers" or "Employees" table. Are you sure none of those groupings are really entity candidates?
To me, they smell unless for some rows or queries you won't be interested in the extra columns. e.g. if for a large portion of your queries you are not selecting the PmFirstName columns, or if for a large subset of rows those columns are NULL.
I like the smells tag.
I use 1 to 1 relationships for inheritance-like constructs.
For example, all bonds have some basic information like CUSIP, Coupon, DatedDate, and MaturityDate. This all goes in the main table.
Now each type of bond (Treasury, Corporate, Muni, Agency, etc.) also has its own set of columns unique to it.
In the past we would just have one incredibly wide table with all that information. Now we break out the type-specific info into separate tables, which gives us much better performance.
For now, to group them, the fields have prefixes (PmFirstName for example) but I'm considering breaking them out into multiple tables with 1:1 relations on the main table.
Create a person table, every database needs this. Then in your project table have a column called PMKey which points to the person table.
Why do you feel that the group of fields are not an entity candidates? If they are not then why try to identify them with a prefix?
Either drop the prefixes or extract them into their own table.
It is valuable splitting them up into separate tables if they are separate logical entities that could be used elsewhere.
So a "Project Manager" could be 1:1 with all the projects currently, but it makes sense that later you might want to be able to have a Project Manager have more than one project.
So having the extra table is good.
If you have a PrimaryFirstName,PrimaryLastName,PrimaryPhone, SecondaryFirstName,SecondaryLastName,SEcondaryPhone
You could just have a "Person" table with FirstName, LastName, Phone
Then your original Table only needs "PrimaryId" and "SecondaryId" columns to replace the 6 columns you previously had.
Also, using SQL you can split up filegroups and tables across physical locations.
So you could have a POST table, and a COMMENT Table, that have a 1:1 relationship, but the COMMENT table is located on a different filegroup, and on a different physical drive with more memory.
1:1 does not always smell. Unless it has no purpose.

Resources