something like unique column in sql. Any suggestion?
Your question is quite "open", so I tried to figure out what you want to do.
If you need to add a column which is not the primary key to store something like a unique ID, you can store there an erlang reference (Ref = make_ref()). which is almost guaranteed to be unique (cycle around 2^82). I don't know what is the behavior in multinode, but if there is a problem it is possible to tag the record with {node(),make_ref()}.
if you want create unique records by the combination of several keys: K1,K2,K3 you can use the tuple {K1,K2,K3} as key of the table and use a set or ordered set. but it will more complex to look into the table
if it it something else, some complementary information could help.
Related
First project using star schema, still in planning stage. We would appreciate any thoughts and advice on the following problem.
We have a dimension table for "product features used", and the set of features grows and changes over time. Because of the dynamic set of features, we think the features cannot be columns but instead must be rows.
We have a fact table for "user events", and we need to know which product features were used within each event.
So it seems we need to have a primary key on the fact table, which is used as a foreign key within the dimension table (exactly the opposite direction from a conventional star schema). We have several different dimension tables with similar dynamics and therefore a similar need for a foreign key into the fact table.
On the other hand, most of our dimension tables are more conventional and the fact table can just store a foreign key into these conventional dimension tables. We don't like that this means that some joins (many-to-one) will use the dimension table's primary key, but other joins (one-to-many) will use the fact table's primary key. We have considered using the fact table key as a foreign key in all the dimension tables, just for consistency, although the storage requirements increase.
Is there a better way to implement the keys for the "dynamic" dimension tables?
Here's an example that's not exactly what we're doing but similar:
Suppose our app searches for restaurants.
Optional features that a user may specify include price range, minimum star rating, or cuisine. The set of optional features changes over time (for example we may get rid of the option to specify cuisine, and add an option for most popular). For each search that is recorded in the database, the set of features used is fixed.
Each search will be a row in the fact table.
We are currently thinking that we should have a primary key in the fact table, and it should be used as a foreign key in the "features" dimension table. So we'd have:
fact_table(search_id, user_id, metric1, metric2)
feature_dimension_table(feature_id, search_id, feature_attribute1, feature_attribute2)
user_dimension_table(user_id, user_attribute1, user_attribute2)
Alternatively, for consistent joins and ignoring storage requirements for the sake of argument, we could use the fact table's primary key as a foreign key in all the dimension tables:
fact_table(search_id, metric1, metric2) /* no more user_id */
feature_dimension_table(feature_id, search_id, feature_attribute1, feature_attribute2)
user_dimension_table(user_id, search_id, user_attribute1, user_attribute2)
What are the pitfalls with these key schemas? What would be better ways to do it?
You need a Bridge table, it is the recommended solution for many-to-many relationships between fact and dimension.
http://www.kimballgroup.com/data-warehouse-business-intelligence-resources/kimball-techniques/dimensional-modeling-techniques/multivalued-dimension-bridge-table/
Edit after example added to question:
OK, maybe it is not a bridge, the example changes my view.
A fundamental requirement of dimensional modelling is to correctly identify the grain of your fact table. A common example is invoice and line-item, where the grain is usually line-item.
Hypothetical examples are often difficult because you can never be sure that the example mirrors the real use case, but I think that your scenario might be search-and-criteria, and that your grain should be at the criteria level.
For example, your fact table might look like this:
fact_search (date_id,time_id,search_id,criteria_id,criteria_value)
Thinking about the types of query I might want to do against search data, this design is my best choice. The only issue I see is with the data type of criteria_value, it would have to be a choice/text value, and would definitely be non-additive.
I need to create a product code which will be generated with a custom function. It will start with a letter, have the id of the category and then have a random 7 digit number. For this, I can set the primary_key to a string and generate the code or I can use FriendlyID. What might be the best for this situation?
Short answer: Use something like friendly_id
The story now:
Choosing a natural key for the primary_key of a table should always be measured well, it has an impact on your data model.
The first issue is regarding related records in other tables. If you will have related tables, the foreign key in those tables should also be VARCHAR and match your generated primary key. If you are not sure what to do, avoid custom primary keys.
Another issue in your question may be:
It will start with a letter, have the id of the category
Is this id the primary key of a Category model? If it's the case, you are generating a key with DB isolation in mind, but re-tighting with this one. Think again for this one.
Go for a slug generated by your function, you will be free for the future. You may create a brand new algorithm and thus only do a once for all change of the slugs. You may even have 2 slugs, the old one which redirects to the new one, and the new one.
A "group" belongs to a "owner" and has many "members". Both the "owner" and the "members" can create "events" under the "group."
Then I need to restrict members to create events under particular groups.
So I tried to add a boolean column to groups table:
When true - this "group" allow all "members" to create "events."
When false - this "group" doesn't allow "members" to create "events", which means only "owner" can create events.
but what should this column name be like?
allows_members_to_create_events
allows_only_owner_to_create_events
requires_owner_authority_to_create_events
other ones?
Or am I doing something wrong with my database design?
I know I'm a little bit too picky about naming but I always have trouble with this kind of naming problem and waste times. So I asked here.
A good name is one of the hardest things to do in coding and I too spend silly time mulling over good naming.
One of my judging criterion is see how the name is being used.
In database point of view i.e. reading from the model source code, only_owner_can_create is a good explanatory name.
In controller point of view, you may want to write if group.allows_members_to_create? or unless group.only_owner_can_create
Having the context where this field will be used will help you greatly to determine the name.
Also you CAN have the best of both worlds - just use alias_methods to add more methods!
Instead of boolean column add numeric column to hold some numeric values. This numeric values are inserted based on the their levels. You have to define these levels in you application.
member_can_create_events would be my pick (single data point that I am).
That would give:
my_group.members_can_create_events?
Though I also agree with Mohanraj that a more complete solution might have users with levels and a column that relates to "users over level X can create events here"... but if you want a quick solution, the boolean column works just fine.
I am currently using a Dbsetlist.Count() to get the primary key of an Autoincremented table where an Row will be saved before any actual saving is performed.. But I feel this approach is not correct but cannot figure out any other alternative purely using Linq can someone suggest how to do this in Linq only?
db.Invoicesets.Add(invoice); //Invoicesets is Invoice table as list for Linq
order.invno = db.Invoicesets.Count(); // Invno is needed as a foreign for Order table
db.Ordersets.Add(order); //
db.SaveChanges();
Do you mean, say, you want to add entity A first so you can use the identity column of A, A.ID as the FK to entity B? If yes, you can use InsertOnSubmit():
db.Invoicesets.InsertOnSubmit(invoice);
order.invo = invoice;
db.orders.InsertOnSubmit(order);
db.SubmitChanges();
You want to be very careful here. What happens if two threads, at the same time, execute:
order.invno = db.Invoicesets.Count();
You will have two orders with the same invno field, which is probably something you don't want.
I'm guessing that field should have a unique constraint on it, and is perhaps your primary key? I don't think there is any LINQ only way to do this, I think you need to make invno an Identity column, that way you'll be assured that it will increment and remain unique.
EDIT
As an aside, you could also generate a GUID for invno in your application code, but obviously you'll have to change the datatype of the invno field in your db.
i was wondering what was the best way to uniquely identify rails objects. im storing them in an index, and currently i have been doing so like
$index.document(#paper.id).add(fields, :variable => variables)
where the #paper.id uniquely identifies it. however when i store other objects, ie #card
$index.document(#card.id).add(fields, :variable => variables)
it's going to overwrite my index because im using the databases autoincrement (which is not unique because they all start and increment by 1). what would be the best solution to having unique identifiers across all my rails objects?
i looked at UUID's and had some reservations about making them my primary key like in...
http://ariejan.net/2008/08/12/ruby-on-rails-uuid-as-your-activerecord-primary-key/
i could always make a separate column i guess. or i could do something like get the object's id and then append it to creation_time. are these good ideas? if not, what would be a good solution for this?
thanks!
I would go with a composite of the object id and the name of the objects table.