سؤال

لدي جدولان، يتم إدراج السجلات بشكل مستمر لهذه الجداول من المصدر الخارجي. دعونا نقول أن هذه الجداول تحافظ على إحصاءات تفاعلات المستخدمين. عندما يقوم المستخدم بالنقر فوق الزر، تتم كتابة تفاصيل ذلك النقر (المستخدم، وقت النقر وما إلى ذلك) إلى أحد الجداول. عندما يتم إضافة MouseVers المستخدم الزر سجل مع تفاصيل إلى جدول آخر.

إذا كان هناك الكثير من المستخدمين يتفاعلون باستمرار مع النظام، فسيكون هناك الكثير من البيانات المتولدة، وسوف تنمو هذه الجداول بشكل كبير.

عندما أريد أن أنظر إلى البيانات، أريد أن أراها في الدقة بالساعة أو اليومية.

هل هناك طريقة، أو أفضل الممارسات تلخيص البيانات بشكل تدريجي (مع جمع البيانات) في الدقة المطلوبة؟

أم أن هناك نهج أفضل لهذا النوع من المشاكل؟

ملاحظة. ما وجدته حتى الآن هو أدوات ETL مثل Talend يمكن أن تجعل الحياة سهلة.

تحديث: أنا أستخدم MySQL في الوقت الحالي، لكنني أتساءل أفضل الممارسات بغض النظر عن DB والبيئة وما إلى ذلك.

هل كانت مفيدة؟

المحلول

تتمثل الطريقة العادية للقيام بذلك على تطبيق مستودع بيانات منخفضة الكمون في الحصول على جدول مقسم مع قسم رائد يحتوي على شيء يمكن تحديثه بسرعة (أي دون الحاجة إلى إعادة حساب المجاميع على الطاير) ولكن مع أقسام زائدة ردمت مع المجاميع وبعد بمعنى آخر، يمكن للقسم الرائد استخدام مخطط تخزين مختلف إلى أقسام زائدة.

يمكن لمعظم المنصات التجارية وبعض منصات RDBMS مفتوحة المصدر (مثل postgresql) دعم الجداول المقسمة، والتي يمكن استخدامها للقيام بهذا النوع من الأشياء بطريقة أو بأخرى. كيف يتم ملء قاعدة البيانات من سجلاتك بمثابة تمرين للقارئ.

في الأساس، يطبق هيكل هذا النوع من النظام:

  • لديك جدول مقسمة على نوع من قيمة التاريخ أو تاريخ التاريخ، المقسمة بالساعة أو اليوم أو أي حبوب يبدو مناسبا. يتم إلحاق إدخالات السجل بهذا الجدول.

  • نظرا لأن نافذة الوقت تنزلق قبالة قسم أو فهارس وظائف دورية أو تلخصه وتحويله إلى حالته "المجمدة". على سبيل المثال، قد تقوم وظيفة في Oracle بإنشاء فهارس نقطية على هذا القسم أو تحديث طريقة عرض مخصصة لتضمين بيانات الملخص لهذا القسم.

  • في وقت لاحق، يمكنك إسقاط البيانات القديمة أو تلخيصها أو دمج الأقسام معا.

  • مع مرور الوقت، يملأ الخلف الوظيفة الدورية وراء القسم الرئيسي. يتم تحويل البيانات التاريخية إلى تنسيق يمضح نفسه لاستعلامات أداء إحصائية أثناء الاحتفاظ بتقسيم الحافة الأمامية سهلة التحديث بسرعة. نظرا لأن هذا التقسيم ليس لديه الكثير من البيانات، فإن الاستعلام عبر مجموعة البيانات بأكملها بسرعة نسبيا.

تختلف الطبيعة الدقيقة لهذه العملية بين منصات DBMS.

على سبيل المثال، فإن تقسيم الجدول على خادم SQL ليس كل ما هو جيد، ولكن يمكن القيام بذلك مع خدمات التحليل (خادم OLAP أن Microsoft Bundles مع SQL Server). يتم ذلك عن طريق تكوين القسم الرائد كوسيلة نقية (يقوم خادم OLAP Server ببساطة بإصدار استعلام مقابل قاعدة البيانات الأساسية) ثم إعادة بناء الأقسام الزائدة كما Molap (يقوم خادم OLAP بتشكيل هياكل البيانات المتخصصة الخاصة بما في ذلك الملخصات المستمرة المعروفة باسم "التجمعات" المستمرة ). يمكن لخدمات التحليل القيام بذلك بشفافية تماما للمستخدم. يمكن إعادة بناء قسم في الخلفية بينما لا يزال Old Rolap One مرئيا للمستخدم. بمجرد الانتهاء من البناء تقبيله في القسم؛ يتوفر المكعب طوال الوقت دون انقطاع الخدمة للمستخدم.

يسمح Oracle بتحديث هياكل التقسيم بشكل مستقل، لذا يمكن إنشاء الفهارس أو قسم تم إنشاؤه على طريقة عرض مخصصة. مع إعادة كتابة الاستعلام، يمكن أن يعمل OptImiser Query في Oracle على أنه يمكن الحصول على الأرقام الإجمالية المحسوبة من جدول الحقائق الأساسية من طريقة عرض مخصصة. سيقرأ الاستعلام الأرقام الإجمالية من الرأي المخصص حيث تتوفر الأقسام ومن قسم الحافة الرائدة حيث لا يفعلون ذلك.

قد يكون postgresql قادرا على القيام بشيء مماثل، لكنني لم تنظر أبدا إلى تنفيذ هذا النوع من النظام عليه.

إذا كنت تستطيع العيش مع انقطاعيات دورية، فيمكن إجراء شيء مماثل بشكل صريح عن طريق القيام بالتميزة وإعداد عرض على البيانات الرائدة والخلفية. يتيح ذلك إجراء هذا النوع من التحليل على نظام لا يدعم التقسيم بشفافية. ومع ذلك، سيكون للنظام انقطاع عابر نظرا لأن الرأي يرغب، لذلك لا يمكنك القيام بذلك حقا أثناء ساعات العمل - في معظم الأحيان سيكون بين عشية وضحاها.

تعديل: اعتمادا على تنسيق ملفات السجل أو خيارات التسجيل المتاحة لك، هناك طرق مختلفة لتحميل البيانات في النظام. بعض الخيارات هي:

  • اكتب نصي باستخدام لغة البرمجة المفضلة لديك التي تقرأ البيانات وتؤدي إلى الخروج من البتات ذات الصلة وإدراجها في قاعدة البيانات. يمكن أن يعمل هذا في كثير من الأحيان إلى حد ما ولكن عليك أن يكون لديك طريقة لتتبع حيث كنت في الملف. كن حذرا من القفل، خاصة على ويندوز. تتيح لك دليون تأمين الملفات الافتراضية على UNIX / Linux القيام بذلك (هذا هو كيف tail -f يعمل) ولكن السلوك الافتراضي على Windows يختلف؛ يجب أن تكون كلا النظامين مكتوبة للعب بشكل جيد مع بعضهما البعض.

  • على نظام UNIX-OID، يمكنك كتابة سجلاتك إلى أنبوب ولديك عملية مشابهة للقراءة أعلاه من الأنبوب. سيكون لهذا أقل كمون للجميع، لكن الفشل في القارئ يمكن أن يمنع طلبك.

  • اكتب واجهة تسجيل لتطبيقك الذي يملأ قاعدة البيانات مباشرة، بدلا من كتابة ملفات السجل.

  • استخدم Bulk Load API لقاعدة البيانات (معظمها إذا لم يكن كل شيء من هذا النوع من API المتوفر) وتحميل بيانات التسجيل في الدفعات. اكتب برنامجا مماثلا للخيار الأول، ولكن استخدم API Load Bulk. هذا ولكن من شأنه استخدام موارد أقل من ملء خط خطيها، ولكن لديه المزيد من النفقات العامة لإعداد الأحمال السائبة. سيكون من المناسب حمولة أقل تواترا (ربما كل ساعة أو يوميا) وسيضع ضغط أقل على النظام بشكل عام.

في معظم هذه السيناريوهات، تتبع المكان الذي أصبحت فيه مشكلة. قد تكون الاقتراع يجب أن يكون الملف إلى التغييرات باهظة الثمن بشكل غير مفيد، لذلك قد تحتاج إلى ضبط المسجل حتى يعمل بطريقة تلعب بشكل جيد مع قارئ السجل الخاص بك.

  • سيكون أحد الخيارات هو تغيير المسجل بحيث يبدأ الكتابة إلى ملف مختلف كل فترة (قل كل بضع دقائق). اجعل قارئ سجلك يبدأ بشكل دوري وتحميل ملفات جديدة لم تتم معالجتها بالفعل. قراءة الملفات القديمة. بالنسبة لهذا للعمل، يجب أن يستند مخطط التسمية للملفات إلى الوقت حتى يعرف القارئ الملف الذي يلتقطه. التعامل مع الملفات لا يزال قيد الاستخدام من خلال التطبيق أكثر fiddly (ستحتاج بعد ذلك إلى تتبع مقدار ما تم قراءته)، لذلك كنت ترغب في قراءة الملفات حتى الفترة الأخيرة فقط.

  • خيار آخر هو نقل الملف ثم اقرأه. يعمل هذا بشكل أفضل على أنظمة الملفات التي تتصرف مثل UNIX منها، ولكن يجب أن تعمل على NTFS. قمت بنقل الملف، ثم اقرأه في الإقامة. ومع ذلك، فإنه يتطلب المسجل لفتح الملف في وضع إنشاء / إلحاق، والكتابة إليه، ثم أغلقه - عدم الاحتفاظ به مفتوحا ومحفوظا. هذا هو بالتأكيد سلوك UNIX - يجب أن تكون عملية الحركة ذرية. على Windows، قد تضطر حقا إلى الوقوف فوق المسجل لجعل هذا العمل.

نصائح أخرى

إلقاء نظرة على rrdtool.. وبعد إنها قاعدة بيانات روبن مستديرة. يمكنك تحديد المقاييس التي تريد التقاطها ولكن يمكن أيضا تحديد الدقة التي تقوم بتخزينها في.

على سبيل المثال، يمكنك تحديد ساعة LAS، يمكنك الحفاظ على معلومات كل ثوان؛ لمدة 24 ساعة الماضية - كل دقيقة؛ في الأسبوع الماضي، كل ساعة، إلخ.

يستخدم على نطاق واسع لجمع الإحصائيات في أنظمة مثل العقدة العصبية و الصبار.

عندما يتعلق الأمر بالتقطيع والبيانات التجميعية (حسب الوقت أو أي شيء آخر)، فإن مخطط ستار (كيمبول ستار) هو حل بسيط إلى حد ما، ولكنه قوي قوي. لنفترض أنه لكل نقرة نقوم بتخزين الوقت (إلى القرار الثاني)، ومعرف المستخدم ومعرف الزر وموقع المستخدم. لتمكين التقطيع والتخلي عن السهل، سأبدأ بجدول بحث محملة مسبقا خصائص الكائنات النادحة نادرا - ما يسمى جداول البعد في العالم DW.

pagevisit2_model_02

ال dimDate يحتوي الجدول على صف واحد لكل يوم، مع عدد السمات (الحقول) التي تصف يوم معين. يمكن تحميل الطاولة مسبقا لسنوات مقدما، ويجب تحديثها مرة واحدة يوميا إذا كانت تحتوي على حقول مثل DaysAgo, WeeksAgo, MonthsAgo, YearsAgo; ؛ خلاف ذلك يمكن أن يكون "تحميل ونسيان". ال dimDate يسمح لسهولة التقطيع لكل تاريخ سمات مثل

WHERE [YEAR] = 2009 AND DayOfWeek = 'Sunday'

لمدة عشر سنوات من البيانات، يحتوي الجدول فقط على صفوف ~ 3650.

ال dimGeography تم تحميل الجدول مسبقا مع مناطق الجغرافيا من الفائدة - عدد الصفوف تعتمد على "القرار الجغرافي" المطلوب في التقارير، فإنه يسمح لتقطيع البيانات

WHERE Continent = 'South America'

بمجرد تحميل، نادرا ما يتغير.

لكل زر من الموقع، يوجد صف واحد في طاولة Dimbutton، لذلك قد يكون للاستعلام

WHERE PageURL = 'http://…/somepage.php'

ال dimUser يحتوي الجدول على صف واحد لكل مستخدم مسجل، يجب تحميل هذا الأمر بمعلومات مستخدم جديدة بمجرد تسجيل المستخدم، أو على الأقل يجب أن تكون معلومات المستخدم الجديدة في الجدول قبل تسجيل أي معاملة مستخدم أخرى في الجداول في الواقع.

لتسجيل النقرات على زر، سأضيف factClick الطاولة.

pagevisit2_model_01

ال factClick يحتوي الجدول على صف واحد لكل نقرة زر واحدة من مستخدم معين في نقطة في الوقت المناسب. لقد استخدمت TimeStamp (القرار الثاني)، ButtonKey و UserKey في مفتاح أساسي مركب للتصفية من النقرات بشكل أسرع من واحد في الثانية من مستخدم معين. لاحظ ال Hour الحقل، يحتوي على جزء الساعة من TimeStamp, ، عدد صحيح في المدى 0-23 للسماح لتزلق سهل في الساعة، مثل

WHERE [HOUR] BETWEEN 7 AND 9

لذلك، الآن علينا أن نفكر في:

  • كيفية تحميل الجدول؟ بشكل دوري - ربما كل ساعة أو كل بضع دقائق - من Weblog باستخدام أداة ETL، أو حل منخفض الكمون باستخدام نوع من عملية تدفق الأحداث.
  • كم من الوقت للحفاظ على المعلومات في الجدول؟

بغض النظر عما إذا كان الجدول يحتفظ بمعلومات ليوم واحد فقط أو لبضع سنوات - يجب تقسيمه؛ Artronthenunbridgew. أوضح التقسيم في إجابته، لذلك سأخطيها هنا.

الآن، هناك بعض الأمثلة على التقطيع والتعديل لكل سمات مختلفة (بما في ذلك اليوم والساعة)

لتبسيط الاستفسارات، سأضيف عرضا لتسليط النموذج:

/* To simplify queries flatten the model */ 
CREATE VIEW vClicks 
AS 
SELECT * 
FROM factClick AS f 
JOIN dimDate AS d ON d.DateKey = f.DateKey 
JOIN dimButton AS b ON b.ButtonKey = f.ButtonKey 
JOIN dimUser AS u ON u.UserKey = f.UserKey 
JOIN dimGeography AS g ON g.GeographyKey = f.GeographyKey

مثال على ذلك

/* 
Count number of times specific users clicked any button  
today between 7 and 9 AM (7:00 - 9:59)
*/ 
SELECT  [Email] 
       ,COUNT(*) AS [Counter] 
FROM    vClicks 
WHERE   [DaysAgo] = 0 
        AND [Hour] BETWEEN 7 AND 9 
        AND [Email] IN ('dude45@somemail.com', 'bob46@bobmail.com') 
GROUP BY [Email] 
ORDER BY [Email]

لنفترض أنني مهتم بالبيانات User = ALL. وبعد ال dimUser هو طاولة كبيرة، لذلك سأقدم عرضا بدونه، لتسريع الاستفسارات.

/* 
Because dimUser can be large table it is good 
to have a view without it, to speed-up queries 
when user info is not required 
*/ 
CREATE VIEW vClicksNoUsr 
AS 
SELECT * 
FROM factClick AS f 
JOIN dimDate AS d ON d.DateKey = f.DateKey 
JOIN dimButton AS b ON b.ButtonKey = f.ButtonKey 
JOIN dimGeography AS g ON g.GeographyKey = f.GeographyKey

مثال على ذلك

/* 
Count number of times a button was clicked on a specific page 
today and yesterday, for each hour. 
*/ 
SELECT  [FullDate] 
       ,[Hour] 
       ,COUNT(*) AS [Counter] 
FROM    vClicksNoUsr 
WHERE   [DaysAgo] IN ( 0, 1 ) 
        AND PageURL = 'http://...MyPage' 
GROUP BY [FullDate], [Hour] 
ORDER BY [FullDate] DESC, [Hour] DESC



لنفترض ذلك التجمعات لا نحتاج إلى الحفاظ على معلومات مستخدم محددة، ولكنها مهتمة فقط في التاريخ والساعة والزر والجغرافيا. كل صف في factClickAgg يحتوي الجدول على عداد لكل ساعة تم النقر فوق زر معين من منطقة جغرافيا محددة.

pagevisit2_model_03

ال factClickAgg يمكن تحميل الجدول بالساعة، أو حتى في نهاية كل يوم - اعتمادا على متطلبات الإبلاغ وتحليلي. على سبيل المثال، دعنا نقول أن الجدول محمول في نهاية كل يوم (بعد منتصف الليل)، يمكنني استخدام شيء مثل:

/* At the end of each day (after midnight) aggregate data. */ 
INSERT  INTO factClickAgg 
        SELECT  DateKey 
               ,[Hour] 
               ,ButtonKey 
               ,GeographyKey 
               ,COUNT(*) AS [ClickCount] 
        FROM    vClicksNoUsr 
        WHERE   [DaysAgo] = 1 
        GROUP BY DateKey 
               ,[Hour] 
               ,ButtonKey 
               ,GeographyKey

لتبسيط الاستفسارات، سأقوم بإنشاء طريقة عرض لتسوية النموذج:

/* To simplify queries for aggregated data */ 
CREATE VIEW vClicksAggregate 
AS 
SELECT * 
FROM factClickAgg AS f 
JOIN dimDate AS d ON d.DateKey = f.DateKey 
JOIN dimButton AS b ON b.ButtonKey = f.ButtonKey 
JOIN dimGeography AS g ON g.GeographyKey = f.GeographyKey

الآن يمكنني الاستعلام عن البيانات المجمعة، على سبيل المثال بحلول اليوم:

/* 
Number of times a specific buttons was clicked 
in year 2009, by day 
*/ 
SELECT  FullDate 
       ,SUM(ClickCount) AS [Counter] 
FROM    vClicksAggregate 
WHERE   ButtonName = 'MyBtn_1' 
        AND [Year] = 2009 
GROUP BY FullDate 
ORDER BY FullDate

أو مع عدد قليل من الخيارات

/* 
Number of times specific buttons were clicked 
in year 2008, on Saturdays, between 9:00 and 11:59 AM 
by users from Africa 
*/ 

SELECT  SUM(ClickCount) AS [Counter] 
FROM    vClicksAggregate 
WHERE   [Year] = 2008 
        AND [DayOfWeek] = 'Saturday' 
        AND [Hour] BETWEEN 9 AND 11 
        AND Continent = 'Africa' 
        AND ButtonName IN ( 'MyBtn_1', 'MyBtn_2', 'MyBtn_3' )

يمكنك استخدام DB تاريخي مثل PI أو Historian. أولئك قد يكونون أكثر من المال مما تريد إنفاقه في هذا المشروع، لذلك قد ترغب في البحث عن أحد بدائل مجانية، مثل حزمة قاعدة بيانات الوقت الحقيقي والتاريخ.

سريعة 'ن الاقتراحات القذرة.

على افتراض أنك لا تستطيع تغيير الجداول الأساسية، أن هذه الجداول سجلت بالفعل تم إضافة صفوف الوقت / التاريخ، ولديك إذن بإنشاء كائنات في DB].

  1. قم بإنشاء طريقة عرض (أو بضعة إطلالة) التي لديها حقل منطقي عليه، مما يولد "عدد فتحة" فريدا عن طريق تقطيع التاريخ في الجداول. شيء مثل:

قم بإنشاء عرض عرض كما حدد A، B، C، Substr (date_field، x، y) slot_number من الجدول؛

المثال أعلاه مبسطة، ربما تريد إضافة المزيد من العناصر من تاريخ + وقت.

على سبيل المثال، يقول التاريخ هو "2010-01-01 10: 20: 23،111"، يمكنك أن تولد المفتاح "2010-01-01 10:00": لذلك قرارا الخاص بك ساعة واحدة].

  1. اختياريا: استخدم العرض لتوليد جدول حقيقي، مثل:

    إنشاء جدول FROZEN_DATA كما حدد * من عرض أين slot_number = 'xxx؛

لماذا تهتم الخطوة 1؟ لا تضطر بالفعل إلى: فقط باستخدام طريقة عرض قد تجعل الأمور أسهل بعض الشيء (من وجهة نظر SQL).

لماذا تهتم الخطوة 2؟ مجرد طريقة للحمل (ربما) الحد من الجداول المزدحمة بالفعل: إذا كنت تستطيع إنشاء DDL ديناميكيا، فيمكنك إنتاج جداول منفصلة مع نسخ من "فتحات" البيانات: والتي يمكنك العمل بها بعد ذلك.

أو يمكنك إعداد مجموعة من الطاولات: واحدة في الساعة من اليوم. قم بإنشاء مشغل لملء الجداول الثانوية: يمكن أن يكون منطق الزناد يثبته الجدول الذي يتم كتابته إليه.

على أساس يومي، عليك إعادة تعيين هذه الجداول: ما لم تتمكن من إنشاء الجداول في الزناد الخاص بك على DB. [من غير المرجح أن أفكر].

اقتراح لم يتم تقديمه (حتى الآن) هو استخدام البوتشد أو مفاهيم قاعدة بيانات مماثلة التي تتعامل مع البيانات غير منظم.

انتظر! قبل القفز علي في رعب، اسمحوا لي أن أنهي.

CouchDB يجمع البيانات غير المنظمة (JSON & C)؛ نقلا عن نظرة عامة فنية من الموقع،

لمعالجة هذه المشكلة لإضافة هيكل مرة أخرى إلى البيانات غير منظم وشبه المنظم، يدمج CouchDB نموذج عرض. الآراء هي طريقة التجميع والإبلاغ عن المستندات في قاعدة بيانات، ويتم بناؤها عند الطلب على إجمالي وانضمام وإبلاغ وثائق قاعدة البيانات. يتم تصميم وجهات النظر بشكل حيوي ولا تؤثر على المستند الأساسي، ويمكنك الحصول على العديد من تمثيلات العرض المختلفة لنفس البيانات التي تريدها.

عرض التعريفات الظاهرية بدقة وعرض المستندات فقط من مثيل قاعدة البيانات الحالية، مما يجعلها منفصلة عن البيانات التي تعرضها وتتوافق مع النسخ المتماثل. يتم تعريف آراء CouchDB داخل مستندات التصميم الخاصة ويمكن النسخ المتماثل عبر مثيلات قاعدة البيانات مثل المستندات العادية، بحيث لا يتم نسخ البيانات فقط في CouchDB، ولكن تصاميم التطبيق بأكملها تكرار أيضا.

من متطلباتك، أستطيع أن أقول لك الحاجة

  • لجمع الكثير من البيانات بطريقة موثوقة
  • الأولوية في السرعة / الموثوقية، وليس على هيكلة البيانات بمجرد الوصول إلى النظام ولا في الحفاظ على / التحقق من الخصائص الهيكلية لما تجمعه (حتى إذا كنت تفوت 1ms من بيانات المستخدم قد لا تكون مشكلة كبيرة)
  • تحتاج إلى بيانات منظمة عندما يتعلق الأمر خارج من DB.

شخصيا، سأفعل شيئا مثل:

  • تم جمعها من ذاكرة التخزين المؤقت بيانات عن العميل (العملاء) وحفظها في رشقات نارية على CouchDB
  • اعتمادا على عبء العمل، احتفظ بمجموعة من DB (مرة أخرى، تم تصميم CouchDB لذلك) في المزامنة بين بعضها البعض
  • كل فاصل يحتوي على خادم يولد طريقة عرض للأشياء التي تحتاجها (أي كل ساعة، إلخ) في حين أن (ق) الاحتفاظ بالبيانات
  • حفظ هذه الآراء (الآن منظم) في قاعدة بيانات مناسبة للتلاعب واللعب مع أدوات SQL، أو أيا كان

النقطة الأخيرة هي مجرد مثال. ليس لدي أي فكرة عما تخطط للقيام به.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top