简体   繁体   English

将数据库中的日期存储为数据库的Java最佳做法是什么?

[英]Is it Java best practice to store dates as longs in your database?

My reason for doing so is that dates stored as date objects in whatever database tend to be written in a specific format, which may greatly differ from what you need to present to the user on the front-end. 我这样做的原因是,作为日期对象存储在任何数据库中的日期往往以特定格式编写,这可能与您需要在前端向用户呈现的内容大不相同。 I also think it's especially helpful if your application is pulling info from different types of data stores. 我还认为,如果您的应用程序从不同类型的数据存储中提取信息,这将特别有用。 A good example would be the difference between a MongoDB and SQL date object. 一个很好的例子是MongoDB和SQL日期对象之间的区别。

However, I don't know whether this is recommended practice. 但是,我不知道这是否是推荐的做法。 Should I keep storing dates as longs (time in milliseconds) or as date objects? 我应该将日期保存为长(以毫秒为单位)或作为日期对象吗?

I can't speak for it in relation to MongoDB, but in SQL database, no, it's not best practice. 我不能说与MongoDB有关,但在SQL数据库中,不,这不是最佳实践。 That doesn't mean there might not be the occasional use case, but "best practice," no. 这并不意味着可能没有偶尔的用例,而是“最佳实践”,没有。

Store them as dates, retrieve them as dates. 将它们存储为日期,将它们检索为日期。 Your best bet is to set up your database to store them as UTC (loosely, "GMT") so that the data is portable and you can use different local times as appropriate (for instance, if the database is used by geographically diverse users), and handle any conversions from UTC to local time in the application layer (eg, via Calendar or a third-party date library). 您最好的办法是设置数据库以将它们存储为UTC(松散地,“GMT”),以便数据是可移植的,并且您可以根据需要使用不同的本地时间(例如,如果数据库由地理位置不同的用户使用) ,并处理从应用程序层到UTC的本地时间的任何转换(例如,通过Calendar或第三方日期库)。

Storing dates as numbers means your database is hard to report against, run ad-hoc queries against, etc. I made that mistake once, it's not one I'll repeat without a really good reason. 存储日期为数字意味着您的数据库很难对报告,对运行即席查询,等等。我犯了那个错误一次,这不是一个我重复没有一个很好的理由。 :-) :-)

It very much depends on: 这在很大程度上取决于:

  • What database you're using and its date/time support 您正在使用什么数据库及其日期/时间支持
  • Your client needs (eg how happy are you to bank on the idea that you'll always be using Java) 您的客户需要(例如,您对将永远使用Java的想法感到高兴)
  • What information you're really trying to represent 您真正想要表达的信息是什么
  • Your diagnostic tools 您的诊断工具

The third point is probably the most important. 第三点可能是最重要的。 Think about what the values you're trying to store really mean. 想想你试图存储的价值究竟是什么意思。 Even though you're clearly not using Noda Time, hopefully my user guide page on choosing which Noda Time type to use based on your input data may help you think about this clearly. 即使您显然没有使用Noda Time,但希望我的用户指南页面根据您的输入数据选择使用哪种Noda Time类型可能会帮助您清楚地思考这一点。

If you're only ever using Java, and your database doesn't have terribly good support for date/time types, and you're only trying to represent an "instant in time" (rather than, say, an instant in a particular time zone, or a local date/time with an offset, or just a local date/time, or just a date...), and you're comfortable writing diagnostic tools to convert your data into more human readable forms - then storing a long is reasonable. 如果使用Java,并且您的数据库对日期/时间类型没有非常好的支持,并且您只是试图表示“及时”(而不是,例如,某个特定时刻)时区,或带偏移的本地日期/时间,或只是本地日期/时间,或只是日期......),您可以轻松编写诊断工具将数据转换为更易读的形式 - 然后存储long是合理的。 But that's a pretty long list of "if"s. 但这是一个很长的“if”列表。

If you want to be able to perform date manipulation in the database - eg asking for all values which occur on the first day of the month - then you should probably use a date/time type, being careful around time zones. 如果您希望能够在数据库中执行日期操作 - 例如询问在该月的第一天发生的所有值 - 那么您应该使用日期/时间类型,在时区周围小心。 (My experience is that most databases are at least shocking badly documented when it comes to their date/time types.) (我的经验是,大多数数据库都至少震撼,当谈到自己的日期/时间类型糟糕记录 。)

In general, you should use whatever type is able to meet all your requirement and is the most natural representation for that particular environment. 通常,您应该使用能够满足您所有要求的任何类型,并且是该特定环境的最自然的表示。 So in a database which has a date/time type which doesn't give you issues when you interact with it (eg performing arbitrary time zone conversions in an unrequested way), use that type. 因此,在具有日期/时间类型的数据库中,当您与其进行交互时不会出现问题(例如,以未请求的方式执行任意时区转换),请使用该类型。 It will make all kinds of things easier. 它将使各种事情变得更容易。

The advantage of using a more "primitive" representation (eg a 64 bit integer) is precisely that the database won't mess around with it. 使用更“原始”表示(例如64位整数)的优点正是数据库不会乱用它。 You're effectively hiding the meaning of the data from the databae, with all the normal pros and cons (mostly cons) of that approach. 你有效地隐藏了数据库中数据的含义 ,具有该方法的所有正常优点和缺点(主要是缺点)。

It depends on various aspects. 这取决于各个方面。 When using the standard "seconds since epoch", and someone uses only integer precision, their dates are limited to the 1970-2038 year range. 当使用标准的“自纪元以来的秒数”,并且有人仅使用整数精度时,它们的日期限制在1970 - 2038年范围内。

But there also is some precision issue. 但也存在一些精确问题。 For example, unix time ignores leap seconds . 例如,unix时间忽略闰秒 Every day is defined to have the same number of seconds. 每天定义为具有相同的秒数。 So when computing time deltas between unix time, you do get some error. 因此,当计算unix时间之间的时间增量时,会出现一些错误。

But the more important thing is that you assume all your dates to be completely known , as your representation does not have the possibility to half only half-specified dates. 但更重要的是,你假设你的所有日期都是完全已知的 ,因为你的代表不可能只有半个指定日期的一半。 In reality, there is a lot of events you do not know at a second (or even ms) precision. 实际上,有很多事件你不知道在第二(甚至ms)精度。 So it is a feature if a representation allows specifing eg only a day precision. 因此,如果表示允许指定例如仅一天的精度,则这是一个特征。 Ideally, you would store dates with their precision information. 理想情况下,您可以使用其精确信息存储日期。

Furthermore, say you are building a calendar application. 此外,假设您正在构建日历应用程序。 There is time, but there also is local time. 有时间,但也有当地时间。 Quite often, you need both information available. 通常,您需要两种信息。 When scheduling overlaps, you of course can do this best in a synchronized time, so longs will be good here. 当安排重叠时,你当然可以在同步的时间内做到最好,所以在这里很长一段时间。 If you however do also want to ensure you are not scheduling events outside of 9-20 h local time , you also always need to preserve timezone information . 但是,如果您还希望确保不在当地时间 9-20小时之外安排活动,则还始终需要保留时区信息 For anything that does span more than one location, you really need to include the time zone in your date representation. 对于任何跨越多个位置的内容,您确实需要在日期表示中包含时区。 Assuming that you can just convert all dates you see to your current local time is quite naive. 假设您可以将您看到的所有日期转换为您当前的当地时间是非常幼稚的。

Note that dates in SQL can lead to odd situations. 请注意,SQL中的日期可能导致奇怪的情况。 One of my favorites is the following MySQL absurdity : 我最喜欢的一个是以下MySQL荒谬

SELECT * FROM Dates WHERE date IS NULL AND date IS NOT NULL;

may return records that have the date 0000-00-00 00:00:00 , although this violates the popular understanding of logic. 可能会返回日期为0000-00-00 00:00:00记录,但这违反了对逻辑的普遍理解。

Since this question is tagged with MongoDB: MongoDB does not store dates in String or what not, they actually store it as a long ( http://www.mongodb.org/display/DOCS/Dates ): 由于这个问题用MongoDB标记:MongoDB不会将日期存储在String中或者不存储,所以它们实际上将它存储为long( http://www.mongodb.org/display/DOCS/Dates ):

A BSON Date value stores the number of milliseconds since the Unix epoch (Jan 1, 1970) as a 64-bit integer. BSON Date值将自Unix纪元(1970年1月1日)以来的毫秒数存储为64位整数。 v2.0+ : this number is signed so dates before 1970 are stored as a negative numbers. v2.0 +:此号码已签名,因此1970年之前的日期将存储为负数。

Since MongoDB has no immediate plans to utilise the complex date handling functions (like getting only year for querying etc) that SQL has within standard querying there is no real downside, it might infact reduce the size of your indexes and storage. 由于MongoDB没有立即计划利用复杂的日期处理函数(比如只获得一年的查询等),SQL在标准查询中没有真正的缺点,它可能会减少索引和存储的大小。

There is one thing to take into consideration here, the aggregation framework: http://docs.mongodb.org/manual/reference/aggregation/#date-operators there are weird and wonderful things you can only with the supported BSON date type in MongoDB, however, as to whether this matters to you depends upon your queries. 这里有一点需要考虑,聚合框架: http//docs.mongodb.org/manual/reference/aggregation/#date-operators有一些奇怪而奇妙的东西你只能使用支持的BSON日期类型但是,MongoDB对您来说是否重要取决于您的疑问。

Do you see yourself as needing the aggregation frameworks functions? 您是否认为自己需要聚合框架功能? Or would housing the extra object overhead be a pain? 或者容纳额外的物体开销是一种痛苦?

My personal opinion is that the BSON date type is such a small object that to store a document without it would be determental to the entire system and its future compatibility for no apparent reason. 我个人认为,BSON日期类型是一个很小的对象,用于存储文档而不会对整个系统及其未来的兼容性造成任何明显的原因。 So, yes, I would use the BSON date type rather than a long and I would consider it good practice to do so. 所以,是的,我会使用BSON日期类型而不是很长时间,我认为这样做很好。

I dont think its a best practice to store dates as long because, that would mean that you would not be able to do any of the date specific queries. 我不认为将日期存储的最佳做法是因为,这意味着您将无法执行任何特定日期的查询。 like : 喜欢 :

where date between 

We also wont be able to get the date month of year from the table using sql queries easily. 我们也无法轻松地使用SQL查询从表中获取一年中的日期月份。

It is better to use a single date format converter in the java layer and convert the date into that and use a single format throughout the application. 最好在java层中使用单个日期格式转换器,并将日期转换为该日期,并在整个应用程序中使用单一格式。

IMHO , storing dates in DB will be best if you can use Strings. 恕我直言,如果你可以使用字符串,最好在DB中存储日期。 Hence avoid unnecessary data going up and down to server , if you don't need all the fields in Calendar. 因此,如果您不需要日历中的所有字段,请避免不必要的数据上下移动到服务器。 There is a lot of data is in Calendar and each instance of Calender is pretty heavy too. 日历中有很多数据,每个Calender实例都很重要。

So store it as String , with only required data and convert it back to Calendar , whenvever you need them and use them. 因此,将它存储为String,仅包含所需数据,并在需要时将其转换回Calendar,并使用它们。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM