Database Headaches - Mind not working today - asp.net

I cant seem to get my head around how to create this
Each Bold Letter is a Database Table
I need this to work with Entity Framework
Product
[ Product belongs to one group]
Product Group - [Computer]
[many to many]
[Group has many items]
[Product belongs to one Group Item]
Product Group Item - [Hard Drive]
[many to many]
[Group Items has Many Fields]
[Fields does not change for each product only changes for each Group Item]
Product Group Item Field - [Form Factor]
[Group Item Fields has many values]
[Field Values Change with each product]
Product Group Item Field Values - [ 3.5" ]
I can pretty much get the first 3 to work
my problem is how to do the last two tables
I hope I explained it clear enough
thanks in advance
alt text http://myimgs.net/images/cjgo.gif
maybe this will help or just hurt who knows
Product = is a harddrive
so:
Group - Computer
GroupItem - Harddrive
GroupItemField - Form Factor : GroupItemFieldValue - 3.5"
GroupItemField - Capacity : GroupItemFieldValue - 600MB
etc...
but the field value changes for each product of type Harddrive but the field does not

I think you may be trying to over-generalise your solution.
It seems to me you want to standardise the information you capture for different kinds of products.
E.g. Hard Drives
1 Supplier1 Model 1a 3.5" 600MB
2 Supplier1 Model 1b 3.5" 200GB
3 Supplier2 Model X 2.5" 600MB
And you want to represent the attributes in a single table:
1 FormFactor 3.5"
1 Capacity 600MB
2 FormFactor 3.5"
2 Capacity 200GB
3 FormFactor 2.5"
3 Capacity 600MB
The problem is that over-generalising like this you lose all the data integrity controls that your RDBMS provides.
You may be better off with:
Product (*Id, Name, GroupId, Supplier, Model, ...)
HardDrive (*Id, FormFactor, Capacity, ...)
Monitor (*Id, Resolution, ...)
Memory (*Id, Capacity, Speed, ...)
Each of the above product specific tables has an optional-to-one reference to Product. With such a design, it becomes impossible to capture Monitor attributes for a hard-drive unless you add a Monitor row for the product.
That said, if you're willing to forego integrity controls, or manage them yourself in code, then looking at sample data helps to produce your schema. (I'm going to use the terminology of attributes.)
AttributeValues (*ProductId, *AttributeId, Value) -- Note a problem here: what type should Value be?
You will need some way of indicating what attributes are allowed for each Group:
HardDrive FormFactor Req
HardDrive Capacity Req
Monitor Resolution Req
Monitor Colour Opt
Memory Capacity Req
Memory Speed Req
GroupAttributes (*GroupId, *AttributeId, IsOptional)
Then you need to indicate the group to which a product belongs (so that you can figure out which values need to be filled in)
1 Supplier1 Model 1a HardDrive
2 Supplier1 Model 1b HardDrive
3 Supplier2 Model X HardDrive
4 Supplier2 Model M1 Monitor
Products (*ProductId, Group, SupplierId, ModelNo)
I'm not sure where your GroupItems fit in.
Relationships
Products.GroupId -> Groups.GroupId
Products.SupplierId -> Suppliers.SupplierId
GroupAttribute.GroupId -> Groups.GroupId
GroupAttribute.AttributeId -> Groups.AttributeId
AttributeValue.ProductId -> Products.ProductId
AttributeValue.AttributeId -> Attributes.AttributeId
NOTE
I've illustrated how you can add columns defining rules for the attribute values. You could do the same for the Attributes table where you'd probably at a minimum need to indicate the data-type of the attribute.
You may notice that it won't be long and you'll soon be replicating the meta-data that your RDBMS provides to define tables and columns. The highly generalised solution does have its benefits such as using a simple template mechanism to capture and view products. But it becomes quite a bit more difficult (in code and processing time) to perform other tasks. So I suggest you consider your requirements holistically against the design.

Related

product variant price view table query

I have question need to query from product table and have many variants and prices, how can I show like below
product. variants. price
==========================
Coke -> Original -> 10$
-> Zero -> 8$
==========================
Pepsi -> Can -> 9$
-> Bottle. -> 10$
==========================
if I have 3 tables : products , variants , product_variant_tranx
any one can help me ?
Thanks
It's a little be late. But this type of question is common for newcomers. I put here my answer for the newcomers who are coming here to search exact type of problems solution.
Every product may generate a unique id like p1,p2,...
Under the products, you enter the variants like variant one, variant two,.. with a unique id(generate when entry, may be visible in the user interface or hidden for working backend) like p1v1,p1v2, with pricing like p1v1 10$,p1v2 8$ etc.
Let's see the tables
Table1. products_table
product_name
product_id
Coke
p1
Pepsi
p2
Table2. variants_table
product_id
variant_name
variant_id
variant_price
p1
Original
p1v1
10$
p1
Zero
p1v2
8$
p2
Can
p2v1
9$
p2
Bottle
p2v2
10$
Call to the user interface
Query1. SELECT product_name,product_id FROM products_table
Then call
Query2. SELECT variant_name,variant_id,variant_price FROM products_table WHERE product_id='getting product id from Query1'
I show the basic logic for newcomers. If having a large number of products and variants then inner looping can jam your server. For this, you may use the same database structures but can use advanced SQL queries.
Relative sources which may help:
https://dev.mysql.com/doc/ (For learning advanced SQL queries)
https://cashflowinventory.com/blog/cash-flow-inventory-tutorial-products-management/ (Get concepts from a likely application's product management interface)

Complex Queries in Firestore / Realtime database and modeling for querying

I have a problem doing complex queries in Firestore database. I have read the documentation countless times so I know where the limitations are, but I wonder whether there is a way to structure the data so it supports my use cases. Let me explain what the use cases first:
I have a list of jobs, and users and I want to able to list/filter jobs according to some criteria and to list/filter users according to some criteria.
Job
JOB ID
- job type (1 of predefined values)
- salary (any number value)
- location (any value)
- long
- lat
- rating (1 - 5)
- views (any number value)
- timeAdded (any timestamp value)
- etc.
User
User ID
- experiences (0, 1 or more of predefined values)
- experience1
- jobCategory
- jobName
- timeEmployed
- experience2
- etc
- languages (0, 1 or more of predefined values)
- language1
- languageName
- proficency
- language2
- etc.
- location (any value)
- long
- lat
- rating (1 - 5)
- views (any number value)
- timeLastActive (any timestamp value)
- etc.
Filtering by field which can only have one value is fine. Even when I add sorting by "timeAdded" or a ragne filter.
1) The problem is when I introduce second range filter, such as jobs with "salary" higher then 15 bucks and at the same time "rating" higher then 4. Is there a way to get around this problem when I have N range filters?
2) Second problem is that I cannot use logical OR. Lets say, filter jobs, where "jobCategory" is Bartender or Server.
3) Another problem is to filter by fields, which can have more then 1 value, e.g. User can speak more than one language. Then if I want to filter users which speak English, it is not possible. Not to mention to filter users who speak e.g. English OR French.
I know I can model the data the way that I use the language as the name of the field, like -english = true, but when I introduce range filter to this, I need to create a Firestore index, which is very inconvenient since I can have around 20 languages and around 50 job types at the same time, and I would have to create indexes all the combinations together with different range filters.. is this assumption correct?
4) How would I filter jobs which up to 20 km from certain position? Radius and the position is on the user to choose.
5) What if I want to filter by all those fields at the same time? E.g. filter certain "jobCategory", location and radius, "salary" higher then something and "rating" higher then something, and sort it all by "timeAdded".
Is this possible with Firestore / Realtime database, can I model the data in some way to support this, or do I have to look for an alternative DB solution? I really like the real-time aspect of it. It will come handy when it is time to implement chat feature to the app. Is it solvable with Cloud functions? I am trying to avoid doing multiple requests, merging them together and sending that to client, since there can be any combination of filters.
If not doable with Firebase, do you know of any alternatives similar to Firestore with better querying options? I really hope I am just missing something :)
Thank you!

Query on use of aggregate functions over recursive groups in microsoft report designer

I have to point out that I'm fairly new to reporting outside of Microsoft Access, and new to the site, so please bear with me!
Stripped down to essential items, my data object has:
CategoryID, ParentCategoryID, TransactionID, TransactionDate, SplitID, CurrencyID and Value.
I don't think this is relevant, but just in case -
A Split has a Category and a Value, with one to many belonging to a Transaction.
Multiple Splits may exist for the same Category & Transaction with
different, or the same, Value (to support different combinations of the other data
items I haven't listed).
A Transaction has a TransactionDate and a CurrencyID, so all Splits
belonging to a Transaction are for the same Currency.
A Category belongs to a Category recursively.
A Split may be assigned a Category at any level in the recursive hierarchy and the crux of my problem is to report Transaction / Split detail under the appropriate Category heading, with a sub-total to include all those details AND the totals of all child Categories.
So, I have a Detail row group holding all the ancilliary data items that aren't relevant and a TransactionIDGroup row group on the same row. I then have a CategoryGroup row group based on CategoryID with a Parent of ParentCategoryID to handle the recursive nature of the data and a CurrencyIDGroup column group to handle the possible multiple currencies involved.
Also in the CategoryIDGroup row group is a total row with the Value cell holding an expression.
If I leave that expression as =Sum(Fields!AccountValue.Value), the report quite nicely totals the Value for each Currency column for all the details specifically in each Category (the default scope), so I thought I needed to make the Sum 'Recursive'. However, you don't seem able to specify the optional Recursive parameter without specifying the scope as well.
If I specify scope as CategoryIDGroup, I get all zero sub-totals. If I use CurrencyIDGroup I get each one being the same report total for the Currency. Anything else either gets me a build error or a combined-currency report total.
The other issue I have is that the recursive child Category groups are reported sequentially underneath the parent Category group (so, outside the header row, detail rows and total row, and not within the group. However, if I can get the total to reflect the children as well as the details at that level, I'd be happy enough, even though it wouldn't seem to add up until you realised what was going on.
What I have in mind is something like:
Category A
Transaction 1 10/02/2011 ...................... £100.00
---------------------- £14.50
Transaction 2 18/03/2011 ...................... $159.34
Category Ai
Transaction 3 18/06/2011 ---------------------- £295.60
Total Category Ai £295.60
Total Category A £410.10 $159.34*
But what I get is this:
Category A
Transaction 1 10/02/2011 ...................... £100.00
---------------------- £14.50
Transaction 2 18/03/2011 ...................... $159.34
Total Category A £114.50 $159.34*
Category Ai
Transaction 3 18/06/2011 ---------------------- £295.60
Total Category Ai £295.60
I guess the fundamental question is - am I asking the impossible? Do I need to take a different approach, perhaps with sub-reports for the details? I've wondered about including a Sum of the values of the child Categories within the data object at each Category level, but is there something simple I'm missing?
Any pointers in the right direction would be greatly appreciated after several days tearing my hair out :)
I have no idea whether there was something simple I missed, but resolved the issue to my satisfaction by including another property in the data object, being the sum of all child categories for each currency, and including a new row to print the sum of that field. Just in case someone else hits just the same question!

Allow users to create new categories and fields on ASP.NET website

We have a db driven asp.net /sql server website and would like to investigate how we can allow users to create a new database category and fields - is this crazy?. Is there any examples of such organic websites out there - the fact that I havent seen any maybe suggest i am?
Interested in the best approach which would allow some level of control by Admin.
I've implemented things along these lines with a dictionary table, rather than a more traditional table.
The dictionary table might look something like this:
create table tblDictionary
(id uniqueidentifier, --Surrogate Key (PK)
itemid uniqueidentifier, --Think PK in a traditional database
colmn uniqueidentifier, --Think "column name" in a traditional database
value nvarchar, --Can hold either string or number
sortby integer) --Sorting columns may or may not be needed.
So, then, what would have been one row in a traditional table would become multiple rows:
Traditional Way (of course I'm not making up GUIDs):
ID Type Make Model Year Color
1 Car Ford Festiva 2010 Lime
...would become multiple rows in the dictionary:
ID ITEMID COLUMN VALUE
0 1 Type Car
1 1 CarMake Ford
2 1 CarModel Festiva
3 1 CarYear 2010
4 1 CarColor Lime
Your GUI can search for all records where itemid=1 and get all of the columns it needs.
Or it can search for all records where itemid in (select itemid from tblDictionary where column='Type' and value='Car' to get all columns for all cars.
In theory, you can put the user-defined types into the same table (Type='Type') as well as the user-defined columns that that Type has (Type='Column', Column='ColumnName'). This is where the sortby column comes into it - to help build the the GUI in the correct order, if you don't want to rely on something else.
A number of times, though, I have felt that storing the user-defined dictionary elements in the dictionary was a bit too much drinking-the-kool-aid. Those can be separate tables because you already know what structure they need at design time. :)
This method will never have the speed or quality of reporting that a traditional table would have. Those generally require the developer to have pre-knowledge of the structures. But if the requirement is flexibility, this can do the job.
Often enough, what starts out as a user-defined area of my sites has had a later project to normalize the data for reporting, etc. But this allows users to get started in a limited way and work out their requirements before engaging the developers.
After all that, I just want to mention a few more options which may or may not work for you:
If you have SharePoint, users already have the ability to create
their own lists in this way.
Excel documents in a shared folder that are saved in such a way
to allow multiple simultaneous edits would also serve the purpose.
Excel documents, stored on the webserver and accessed via ODBC
would also serve as single-table databases like this.

pull everything from db and then compute stats?

I am working on an auto trade website. On the page where Ad list gets displayed, I plan to display the number of Ad for different categories: for example, for location: I will display something like "Vancouver (50), Richmond (12), Surrey (20)". For vehicle make, the following will be shown "Honda (20), Ford(12), VW (24)".
I am not sure if I should pull ALL the ad from the db into a List first, bind one page of the result to gridview control, and then compute stats for each category using Linq. if course I will limit the number of rows pulled from the db using some kind of condition - maybe set the MAX # of rows to be returned as 500.
My major concern is - is this going to be a memory hog?
It is bad idea to count rows in the memory. Use
SELECT COUNT() FROM... [ GROUP BY ]
which is much more efficient.
Also review possibility to cache these values. Assuming that multiple people loads your page simultaneously, but count of cars don't changes quicker then once per 1 minute - apply caching strategy to obsolete values over 1 min.

Resources