開源日報 每天推薦一個 GitHub 優質開源項目和一篇精選英文科技或編程文章原文,堅持閱讀《開源日報》,保持每日學習的好習慣。
今日推薦開源項目:《切切樂 shapez.io》
今日推薦英文原文:《Don』t Use Database Generated IDs》

今日推薦開源項目:《切切樂 shapez.io》傳送門:GitHub鏈接
推薦理由:一款將圖形進行各種處理以達成任務目標的遊戲,外表上簡單易懂,但是實際操作起來需要考慮很多效率上的因素,尤其是後期圖形更加複雜會讓你的布局走線需要各種重排,steam 上的正式版也不算貴,演示版玩爽了完全可以考慮入一個。

今日推薦英文原文:《Don』t Use Database Generated IDs》作者:Nicklas Millard
原文鏈接:https://medium.com/swlh/dont-use-database-generated-ids-d703d35e9cc4
推薦理由:把應用程序需要用到的 ID 交給應用程序自己解決

Don』t Use Database Generated IDs

Stop letting the database be in charge of your application

You』ve probably let databases generate IDs for your application at least once.

But, what if I told you it』s a terrible idea when developing applications? Using auto-incremented integer IDs is the worst.

Lets unlearn this horrific practice once and for all.

I』m sure this stands in sharp contrast to what you learned in the Relational Databases 101 college course and the countless youtube tutorials you』ve watched when learning how toCREATE TABLE UsingTerribleIds ().

The key message is so important I』ll just write it here at the beginning in case you don』t have time to read the whole story.
  • Generate your IDs at the application level. Not at the persistence level.
That』s it. You』re free to go on your merry way.

Or, stay put if you want to know more about why database generated IDs are awful and want to learn how I approach ID generation at client projects.

So, what』s the issue with having the database generate your application』s IDs?

1 What』s most problematic is you』re delegating an extremely important aspect of your application to third party software. You lose control of your application the moment you off-load this responsibility.

2 You』re likely to apply some bad practices while designing your entity classes just to make it easier working with a persistence framework, such as EntityFramework in C# .NET.

One of the worst offenders I see junior programmers do is having public ID setters.

Just terrible to witness.

3 You』re making unit testing more difficult than it needs to be. You suddenly rely on a third party providing your entities with IDs.

Say you』ve figured that a public ID setter is essentially a terrible sin, and you don』t want calling code to set the ID either. Your class would instead look something like this below.

Your ORM of choice is possibly still able to set the id field through reflection — you know, nothing is really safe from reflection…

But, how would you unit test this? The id field is set to 0 on instantiation. Instantiating more than one TerribleBook would leave you with identity collision, as now more than one TerribleBook has the same id, even tho your should represent two separate entities.

How do we then generate more suitable IDs and reclaim responsibility?

The solution is honestly dead simple. Just have a look at the snippet below.

Let』s walk thru this code, as every change from the TerribleBook to FixedBook might not be obvious to everyone.

First off, the ID is now a string instead of an integer. This allows better scalability. But remember limiting the length of the field in the database. Don』t ever use VARCHAR(MAX) for fields with a known length — it』ll eat memory.

Then, we make the constructor private and instantiate new objects using the static factory method. This allows us to abstract the instantiation logic from the caller and even provides us the opportunity to use polymorphism — we might want to return a Null Object instead of throwing.

Notice we』re still taking the id as a constructor parameter. But we are in charge of generating and providing the id (on line 18). Not the database.

The Guid.NewGuid().ToString("D") just ensures we』ll get a hyphen formatted GUID. I like using GUIDs, but you』re free to build your own ids which ever way makes sense to your business and application needs.

Now we』re back in control.

「But entities will no longer be stored in sequence!」

You』re completely right about that. But why is that even a concern? I know junior developers like to see their entities being stored in a sequenced manner — even if it often has no business impact.

If you』d really need to store things in sequence, just provide a Created datetime column.
下載開源日報APP:https://openingsource.org/2579/
加入我們:https://openingsource.org/about/join/
關注我們:https://openingsource.org/about/love/