field_data_commerce_line_items vs commerce_line_item in Drupal Commerce - database

I've realized that there are two tables with similar names in my DB:
field_data_commerce_line_items and commerce_line_item.
Can someone explain the purpose or reason of having them? I mean the difference between them.
My understanding is that field_data_commerce_line_items is a reference field on an order that references a line in the commerce_line_item table on field_data_commerce_line_items.commerce_line_items_line_item_id = commerce_line_item.line_item_id.
However still not getting the overall picture.

In Drupal an entity can reference multiple entities via a field reference. The references aren't necessarily unique, but the entities are.
field_data_commerce_line_items is a multi-value field reference that associates Line Item entities to a specific Order.
commerce_line_item represents the unique Line Item entity.

Related

Designing a database with similar, but different Models

I have a system whereby you can create documents. You select the document type to create and a form is displayed. Data is then added to the form, and the document can be generated. In Laravel things are done via Models. I am creating a new Model for each document but I don't think this is the best way. An example of my database :
So at the heart of it are projects. I create a new project; I can now create documents for this project. When I select project brief from a select box, a form is displayed whereby I can input :
Project roles
Project Data
Deliverables
Budget
It's three text fields and a standard input field. If I select reporting doc from the select menu, I have to input the data for this document (which is a couple of normal inputs, a couple of text fields, and a date). Although they are both documents, they expect different data (which is why I have created a Model for each document).
The problems: As seen in the diagram, I want to allow supporting documents to be uploaded alongside a document which is generated. I have a doc_upload table for this. So a document can have one or more doc_uploads.
Going back to the MVC structure, in my DocUpload model I can't say that DocUpload belongs to both ProjectBriefDoc and ProjectReportingDoc because it can only belong to one Model. So not only am I going to create a new model for every single document, I will have to create a new Upload model for each document as well. As more documents are added, I can see this becoming a nightmare to manage.
I am after a more generic Model which can handle different types of documents. My question relates to the different types of data I need to capture for each document, and how I can fit this into my design.
I have a design that can work, but I think it is a bad idea. I am looking for advice to improve this design, taking into account that each document requires different input, and each document will need to allow for file uploads.
You don't need to have a table/Model for each document type you'll create.
A more flexible approach would be to have a project_documents table, where you'll have a project_id and some data related to it, and then a doc_uploads related to the project_documents table.
This way a project can have as many documents your business will ever need and each document can have as many files as it needs.
You could try something like that:
If you still want to keep both tables, your doc_upload table in your example can have two foreign keys and two belongsTo() Laravel Model declarations without conflicts (it's not a marriage, it's an open relationship).
Or you could use Polymorphic Relations to do the same thing, but it's an anti-pattern of Database Design (because it'll not ensure data integrity on the database level).
For a good reference about Database Design, google for "Bill Karwin" and "SQL Antipatterns".
This guy has a very good Slideshare presentation and a book written about this topic - he used to be an active SO user as well.
ok.
I have a suggestion..you don't have to have such a tight coupling on the doc_upload references. You can treat this actually as a stand alone table in your model that is not pegged to a single entity.. You can still use the ORM to CRUD your way through and manage this table..
What I would do is keep the doc_upload table and use it for all up_load references for all documents no matter what table model the document resides in and have the following fields in the doc_upload table
documenttype (which can be the object name the target document object)
documentid_fk (this is now the generic key to a single row in the appropriate document type table(s)
So given a document in a given table.. (you can derive the documenttype based on the model object) and you know the id of the document itself because you just pulled it from the db context.. should be able to pull all related documents in the doc_upload table that match those two values.
You may be able to use reflection in your model to know what Entity (doc type ) you are in.. and the key is just the key.. so you should be able.
You will still have to create a new model Entity for each flavor of project document you wish to have.. but that may not be too difficult if the rate of change is small..
You should be able to write a minimum amount of code to e pull all related uploaded documents into your app..
You may use inheritance by zero-or-one relation in data model design.
IMO having an abstract entity(table) called project-document containing shared properties of all documents, will serve you.
project-brief and project-report and other types of documents will be children of project-document table, having a zero-or-one relation. primary key of project-document will be foreign key and primary key of the children.
Now having one-to-many relation between project-document and doc-upload will solve the problem.
I also suggest adding a unique constraint {project_id, doc_type} inside project-document for cardinal check (if necessary)
As other answers are sort of alluding to, you probably don't want to have a different Model for different documents, but rather a single Model for "document" with different views on it for your different processes. Laravel seems to have a good "templating" system for implementing views:
http://laravel.com/docs/5.1/blade
http://daylerees.com/codebright-blade/

Database design to support dynamic entities

OK, I don't know whether this question belong to this place, but you will suggest me if I'm wrong.
I have some entities which has almost same attributes, differences is in maybe 2-3 columns.
Because of those different columns, I can't create one table with columns that are union of attributes of every entity, because new entity type will require changing table design adding new columns specific to that entity type.
Instead, currently working design is that every specific entity has own table.
But, if new type of entity come on scene, I must create new table, which is totally bad idea.
How can I create one table which consists shared attributes for each type of entity, and some additional mechanism to evidence entity-unique attributes?
So, idea is to easy add new types of objects, without changing database design, configuring only part that deal with unique columns.
P.S. Maybe I'm not clear, but I will add more description if is it needed.
I had a design like that once. What I did was I created a table that housed all the shared properties. Then, I had separate tables for the distinct values. I used joins to match a specific entity to its shared table row. I had less than 10, so my views that used unions I just updated when I added a new entity. But, if you used a naming convention, you could write stored procs that find the table names dynamically and do the unions and joins on the fly. In my case, I used a base class and specific classes to make a custom data layer.
Another possibility is to have a generic table that's basically name/value pairs and a table the represents your shared properties. By joining the tables together, you could have any number of entity specific properties for your entities. It's not very efficient and the SQL would get weird, but I've seen it done.
One solution is to store the common parts in one table, and the specific parts in tables specific to that entity.
eg: To have a set of people, some of whom are managers...
Person Table
PersonID
PersonName
Manager Table
ManagerID
PersonID
DepartmentManaged
As soon as you go down the path of having one table with variable field meanings - effectively an Entity Attribute Value design - you find yourself in querying hell.
Perhaps not the best or most academic, but what about this kind of "open structure" ?
MainTable: all common fields
SpecialProperties: extra properties, as required
- MainRecordId (P, F->MainTable)
- PropertyName (P)
- PropertyText
- PropertyValue (for numeric values)

Database Is-a relationship

My problem relates to DB schema developing and is as follows.
I am developing a purchasing module, in which I want to use for purchasing items and SERVICES.
Following is my EER diagram, (note that service has very few specialized attributes – max 2)
My problem is to keep products and services in two tables or just in one table?
One table option –
Reduces complexity as I will only need to specify item id which refers to item table which will have an “item_type” field to identify whether it’s a product or a service
Two table option –
Will have to refer separate product or service in everywhere I want to refer to them and will have to keep “item_type” field in every table which refers to either product or service?
Currently planning to use option 1, but want to know expert opinion on this matter. Highly appreciate your time and advice. Thanks.
I'd certainly go to the "two tables" option. You see, you have to distinguish Products and Services, so you may either use switch(item_type) { ... } in your program or entirely distinct code paths for Product and for Service. And if a need for updating the DB schema arises, switch is harder to maintain.
The second reason is NULLs. I'd advise avoid them as much as you can — they create more problems than they solve. With two tables you can declare all fields non-NULL and forget about NULL-processing. With one table option, you have to manually write code to ensure that if item_type=product, then Product-specific fields are not NULL, and Service-specific ones are, and that if item_type=service, then Service-specific fields are not NULL, and Product-specific ones are. That's not quite pleasant work, and the DBMS can't do it for you (there is no NOT NULL IF another_field = value column constraint in SQL or anything like this).
Go with two tables. It's easier to support. I once saw a DB where everything, every single piece of data went in just two tables — there were pages and pages of code to make sure that necessary fields are not NULL.
If I were to implement I would have gone for the Two table option, It's kinda like the first rule of normalization of the schema. To remove multi-valued attributes. Using item_type is not recommended. Once you create separate tables you dont need to use the item_type you can just use the foreign key relationship.
Consider reading this article :
http://en.wikipedia.org/wiki/Database_normalization
It should help.

Solr - How to index on multiple entities?

I have two tables contacts and inventory. These two tables are not related. I want to index these two tables and search using Solr.
Is this possible?
If some part of your application needs to search for contacts, and another one needs to search in the inventory, create two separate indices. Storing wildly different data in the same index is almost never a good idea, it complicates things unnecessarily. As the Solr wiki wisely says:
The more heterogeneous (different
kinds of data) you have in one field
or in one index, the less useful it
is.
You don't need to have multiple Solr instances to accomodate multiple indices, you can easily manage this with multi-core.
I found a very helpful answer to this question here, including some guidance on using "multiple indexes" vs. "multiple document types in one index". The post also links to example code on github that I found very useful.
Yes, you can do that. Simply create a Solr schema, that contains all fields necessary for both tables and add another field, that contains the table name. During indexing, add the table name property to the fields you want to index. During searching also always include a query parameter for the table name field.
As an alternative, you can setup multiple instances of Solr. But you should do this only, if we are talking about massive amounts of data here (like millions of table rows).

Basic Database design. Use a another table or colum

I have a table that holds information about a particular Object, Say Item and has columns
ItemID, ItemName, price, ItemListingType.....LastOrderDate
One of the bits of information, ItemListingType could be one of 10 different types
such as:
private, gov, non-gov, business... etc (strings) and could be extended to more types in future.
Should I be using a column inside table ITEM or should I Use a separate table with two columns and put a foreign key in Item table to reference that (a one to many relationship)? Like:
ListingTypeID int
ListingTypeName varchar(MAX)
EDIT: how many values for a column, you will consider to use another table for that
2, 4 or what ?
Thanks
Use a separate table to store this kind of reference data. This is a tenet of normalization and will also enable easier caching because you are separating read-only and read-write data. my two cents...
Separate table.
What if you have a listing type not yet used?
Or delete the last item with type x?
Or need to change a value?
These are insert, update and delete anomalies, which is one reason for normalisation
I would definitely go for a "lookup" style column; that way you are not stumped when there future additions to the list of permissible listing types. You are also reducing redundancy and making it easier to change the designation of aparticular type of listing (if "gov" changes to "government agencies", then you only have to change it in one place).
You should do it with the second table that holds the ListingTypes and link to the id of that table from the one with the Objects...
Take a look at Relational Database and Relational model.
In situations like this I ask myself:
Can the Item have an undetermined number of Listing types? If yes, different table.
Do the specs say that there will never be more than 3 types? Depends. Sometimes I'll still go with a separate table, sometimes not. You get a feel for this after a while.
Will the Item ALWAYS have a single listing type? If yes, same table, single column.
Now to take matters one step further.
If an Item has zero or more listing types AND those listing types are actually shared (in other words two items could have the same listing type, then we have 3 tables: Items, ListingTypes, and a cross reference table to support a many to many relationship.
Clasically, you should use an extra table, because you won't have any duplication that way. It will also allow you to change the value for this listing in a single place. However, if you are very very sure that no types will be added, keep the column.

Resources