How to support GUID in Windows Azure Mobile services - guid

It is specifically mention that WAMS needs a int ID column to work in SQL Azure. However when developing enterprise apps over distributed databases, GUIDs are the preferred Primary key to have. How does one get around avoiding int ID column and support GUID?
If that cannot be done then how does one go about syncing data on the cloud from multiple standalone databases on various tablets/mobile the app using WAMS is running on?

An update on this issue - as of last week, the mobile services now support arbitrary strings as the ids for the column - check out this post for more information. You can now insert data with an 'id' value (which you couldn't before), so you can use a Guid value on insert. Also, if you don't send anything on the Id column on insert (or that value is set to null), the server will by default generate an unique identifier for the column.

At present, I don't think that its possible to use a GUID in the ID column. The documentation for the Mobile Services server side scripts specify that for the Delete function, the ID must be a javascript Number type. As far as I can see, all of the available sample code, and the code that you can download from the portal is quite explicit in using an integer type for the ID.
You'll have to come up with a way of generating a unique integer value whenever a new record is created. The example here uses a tick count in Insert script, which is probably OK for a low volume application, but it would need to be made more robust, perhaps by generating a number based on the user's identity and combining it with the tick count.

I'm a little late to this but I have found you can use a GUid as a primary key to a mobile services table. A couple of points though. Set the JSON property to lower case "id" and use a nullable guid, this allows inserting when there a default on the id column (NewId())
[JsonProperty(PropertyName = "id")]
public Guid? Id { get; set; }
Ash..

Related

enforce case-insensitive value for unique key constraint in cosmosDB?

we have a sql container. We’d like to enforce case-insensitive unique constraint on a particular property (say, ‘Name’. if a document's Name is ‘ALICE’, no other document in that logical partition shall have ‘alice’ as Name).
One solution might be introducing another property LowerCaseName and enforce the natively supported unique key config on path /LowerCaseName. Every time Name is updated, we make sure LowerCaseName is always updated as the lower-case version of Name in the same request.
I’m not sure if this is the best practice for this problem? Thanks.
public MyDocumentModel
{
string Name {get; set;}
string LowerCaseName {get; set;}
}
From the documentation here:
In Azure Cosmos DB's SQL (Core) API, items are stored as JSON values.
These JSON values are case sensitive. When you choose a property as a
unique key, you can insert case sensitive values for that property.
For example, If you have a unique key defined on the name property,
"Gaby" is different from "gaby" and you can insert both into the
container.
Based on this, I believe your approach for having a 2nd property to enforce unique key is correct.

Whats the proper way to implement a unique secondary index on a DynamoDB table that has no range key?

I'm a bit confused by how to properly set up secondary indexes in DynamoDB.
the documentation states secondary indexes are for tables which have a hash and rangekey, but in my case, I have no need of the range key.
The scenario is basically like this. I have a list of mobile clients which will call into my API. those clients are identified by a 6 character unique client ID. Each client also has a unique device ID, which is basically a long GUID -- quite long and inconvenient to use as the primary key.
The question comes when a client registers itself it sends is device ID (the long GUID) in a registration request and the server generates the unique clientID (the six char unique ID) which it returns to the client for future communication. One of the checks that the server side must do is make sure the request is not a duplicate registration, i.e. that the deviceID is not already present in the table under another client ID.
In a SQL table, I would have the clientID be the primary key, and 'd just define the a unique index on the deviceID field, but it seems like I can't do that in DynamoDB, since I only have a hash key on the table, not a hash and range key. I could do a query to find out if there's a dupe deviceID somewhere but that would seem to require a table scan which I'd like to avoid.
What's the proper way to set up something like this in DynamoDB? Do I just use a dummy range key like "foo" on all my rows and use a local secondary index? Seems inefficient somehow.
I personally don't like to use indexes.
What I recommend is to keep two tables.
DEVICES
Hash: device_id
attribute: client_id
CLIENT_DEVICES
Hash: client_id
Range: device_id
This allows you to reason about whether a client has devices, which devices, as well as ask for a device if it attached to a client.
This IMO is more readable than global/local secondary indexes.

Database Table Data Types To Store Key/Value Cache

I am working on a project that requires key/value caching function but the application will exist in a very limited environment that does not support any of the go-to industry standard memory caching methods such as ASP.NET Cache, memcached, AppFabric.
The only option we have in this restrictive environment is a MS SQL database. We have to create a simple key/value table to meet our key/value caching needs. We will most likely serialize the data as JSON but I am not sure what would be the best data type for the key. It will obviously need to be a unique key and need to be readable by the programmer getting and setting the cache. It also needs to be a fast look up since we will already be loosing performance not having access to an "in memory" cache solution.
I am use to having my primary key column be an int or bigint value. In this case should the primary key (the cache key) be a char or varchar data type as all queries will be:
SELECT value FROM CacheTable WHERE key = 'keyname'
I also saw posts about using an md5 hash but other posts pointed out that hashing cannot be relied on to produce unique keys all the time. I'm basically after some advice on the data type and rather or not the 'key' column should be the primary key or if I should still create an int or bigint primary key (even though it probably will not be used).
The end result we are after is creating a caching class similar to .NET's native caching where we can create a static class that pulls from the database table such as:
CustomDatabaseCache.Set(string key, object value);
CustomDatabaseCache.Get(string key)
I think in your scenario having a clustered primary key on your keyname column would work fine. However, it's worth experimenting with fill factors, because you want a fill factor that is low enough that you don't cause excessive page splits, but one that is high enough to keep the number of page reads low.
A clustered IDENTITY index works better in terms of eliminating page splits on the clustered index - and you could use a unique index on keyname which used an INCLUDE clause to include your values. However - in your case, I don't see the benefit in doing that because you'd have exactly the same page-split problem on your unique index, and the clustered index on keyname would be no more expensive to read because you wouldn't have any extra columns. Plus you would then have index update cost on two indexes for write.
Hope that helps.

GUID not being generated automatically when db.submitchanges()

I have a couple of tables I ported over to a new database. Everything is exactly the same from the legacy one to the new one. The back-end code that submits the user generated data to the database is also the same. When I submit changes to the database, all of the submitted information populates the correct columns but the column that stores the GUID populates with all 0's. When I enter in the columns manually using SQL Server Management Studio, the GUID gets populated as it does in the legacy version. Am I missing something?
I've had a similar issue with Entity Framework in the past, even though I have newid() set as default/initial value on the column. Due to time constraints, I didn't spend much time to resolve it and instead set the Guid property manually/explicitly to Guid.NewGuid() prior to saving.
When you ported over the tables, you must not have ported over the default value for one of the columns. E.g.
CREATE TABLE blah (
blahID UNIQUEIDENTIFIER PRIMARY KEY DEFAULT NEWID()
)

Where should I manage the createdBy, modifiedBy, createDate, and modifiedDate?

I want to insert the createdBy, modifiedBy, createDate, modifiedDate columns in every database table for manage user activity.
This is the first time I try to do this. Is there a best practice I could follow? Any design pattern good to manage this?
My first thought is to do this in my business logic layer, and in every business classes' insert and update method, i do something like this:
class.createDate = DateTime.Now;
or
class.modifiedDate= DateTime.Now;
class.modifiedBy = CurrentUser.Id;
or
class.createdBy = CurrentUser.Id;
Or there are much better way?
Bryan
This depends on what types of business objects you are managing, and what the rules are around what the create/modified data is needed for. In most cases, this is a database audit trail, and there is no need for this information in the business logic layer. In that case, this information should live at the database level only. If you are using an ORM, that might mean you keep the data with your objects anyway. If you are using stored procs, then they all need to know how to take a user name to tag the record with. The datetimes can be handled by setting a default value of GetDate() on the column.
Well one thing to consider is what time do you want stamped? Do you want the time of the application server or the time on the database server? I always go for the DB server. So in that case the stored procedure (or SQL statements) should be getting current time.
-Krip
You should manage CreatedDate and ModfiedDate at database label only. Default value of the CreatedDate should be Getdate()/SYSDATE and you don’t need to set this value. For ModifiedDate again set the GETDATE()/SYSDATE on every update.
You only need to pass the ModifiedBy userid from your application to the database, in case of insert set the userid for both the column and in the case of update only update the Modified by userId column.
For createdBy and modifiedBy, I usually set this in my business layer using the username of the current user. For createDate and modifiedDate I do this in the 'after' triggers in the database.

Resources