开源日报 每天推荐一个 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/