Tuesday, 26 September 2017

Gleitender Mittelwert Ohne Speicherung


Die meisten Leute sind vertraut mit der Phrase, quotthis tötet zwei Vögel mit einem stonequot. Wenn Sie nicht sind, bezieht sich die Phase auf einen Ansatz, der zwei Ziele in einer Handlung anspricht. (Leider sind die meisten von uns don39t wollen Steine ​​an unschuldigen Tieren zu werfen) Heute werde ich gehen, um einige Grundlagen auf zwei große Funktionen in SQL Server zu decken: der Columnstore-Index (nur in SQL Server Enterprise verfügbar) und Den SQL-Abfrage-Speicher. Microsoft tatsächlich implementiert den Columnstore-Index in SQL 2012 Enterprise, obwohl they39ve es in den letzten beiden Versionen von SQL Server verbessert. Microsoft führte den Query Store in SQL Server 2016. Also, was sind diese Funktionen und warum sind sie wichtig Nun, ich habe eine Demo, die beide Funktionen vorstellen und zeigen, wie sie uns helfen können. Bevor ich weiter gehen kann, decke ich auch diese (und andere Funktionen von SQL 2016) in meinem Artikel des CODE-Magazins über neue Funktionen SQL 2016. Als Grundeinführung kann der Columnstore-Index helfen, Abfragen zu beschleunigen, die über große Datenmengen scanaggregieren und Durchsucht der Abfragespeicher Abfrageausführungen, Ausführungspläne und Laufzeitstatistiken, die Sie normalerweise benötigen, um manuell zu sammeln. Vertrauen Sie mir, wenn ich sage, diese sind große Eigenschaften. Für diese Demo verwenden wir die Microsoft Contoso Retail Data Warehouse-Demo-Datenbank. Locker gesprochen, Contoso DW ist wie Quota wirklich großen AdventureWorksquot, mit Tabellen mit Millionen von Zeilen. (Die größte AdventureWorks-Tabelle enthält höchstens 100.000 Zeilen). Sie können die Contoso DW-Datenbank hier herunterladen: microsoften-usdownloaddetails. aspxid18279. Contoso DW funktioniert sehr gut, wenn Sie die Leistung bei Abfragen gegen größere Tabellen testen möchten. Contoso DW enthält eine Standard Data Warehouse Fact-Tabelle namens FactOnLineSales mit 12,6 Millionen Zeilen. Das ist sicher nicht die größte Data Warehouse-Tabelle der Welt, aber es spielt auch keine Rolle. Angenommen, ich möchte Produktumsatz für 2009 zusammenfassen und die Produkte einstufen. Ich könnte Abfrage der Tatsache Tabelle und beitreten, um die Product Dimension Tabelle und verwenden Sie eine RANK-Funktion, wie folgt: Here39s eine partielle Ergebnismenge der oberen 10 Zeilen, von Total Sales. Auf meinem Laptop (i7, 16 GB RAM), die Abfrage dauert überall von 3-4 Sekunden ausgeführt werden. Das scheint nicht wie das Ende der Welt zu sein, aber einige Benutzer erwarten nah-sofortige Resultate (die Weise, die Sie nahe-sofort Ergebnisse sehen konnten, wenn Sie Excel gegen einen OLAP Würfel verwenden). Der einzige Index, den ich derzeit auf dieser Tabelle haben, ist ein gruppierter Index auf einem Umsatzschlüssel. Wenn ich den Ausführungsplan betrachte, macht SQL Server einen Vorschlag, einen Deckungsindex zu der Tabelle hinzuzufügen: Jetzt, nur weil SQL Server einen Index vorschlägt, bedeutet doesn39t, dass Sie blind Indizes für jede quotmissing Indexquot-Nachricht erstellen sollten. In diesem Fall erkennt SQL Server jedoch, dass wir basierend auf Jahr filtern und den Produktschlüssel und den Verkaufsbetrag verwenden. So schlägt SQL Server einen Deckungsindex vor, mit dem DateKey als das Indexschlüsselfeld. Der Grund, den wir diesen quotcoveringquot Index nennen, ist, weil SQL Server entlang der nicht-key fieldsquot, die wir in der Abfrage verwendet haben, zitiert wird, zitiert für das ridequot. Auf diese Weise, SQL Server doesn39t müssen die Tabelle oder den gruppierten Index an allen Datenbank-Engine verwenden können einfach die Abdeckung Index für die Abfrage verwenden. Covering-Indizes sind in bestimmten Data Warehousing-und Reporting-Datenbank-Szenarien beliebt, obwohl sie zu einem Preis der Datenbank-Engine, die sie erhalten kommen. Hinweis: Abdecken Indizes gibt es schon seit einer langen Zeit, so dass ich haven39t noch abgedeckt den Columnstore-Index und den Query Store. Also, ich werde den Deckungsindex hinzufügen: Wenn ich die gleiche Abfrage, die ich vor einem Moment ausgeführt habe (diejenige, die die Verkaufsmenge für jedes Produkt zusammengefasst hat) erneut ausführen, scheint die Abfrage manchmal um eine Sekunde schneller zu laufen, und ich bekomme eine Der einen Index-Suchvorgang anstelle eines Index-Scans verwendet (unter Verwendung des Datumschlüssels auf dem Deckungsindex, um den Umsatz für 2009 abzurufen). Also, vor dem Columnstore-Index, könnte dies eine Möglichkeit, diese Abfrage in viel älteren Versionen von SQL Server zu optimieren. Es läuft ein wenig schneller als das erste, und ich bekomme einen Ausführungsplan mit einem Index Seek anstelle eines Index-Scan. Allerdings gibt es einige Probleme: Die beiden Ausführungsoperatoren quotIndex Seekquot und quotHash Match (Aggregate) beide beide im Wesentlichen bedienen quotrow by rowquot. Stellen Sie sich dies in einer Tabelle mit Hunderten von Millionen von Zeilen vor. In Verbindung stehende, denken über den Inhalt einer Faktentabelle: In diesem Fall können ein einzelner Datumschlüsselwert andor oder ein einzelner Produktschlüsselwert über Hunderte von Tausenden von Zeilen wiederholt werden (denken Sie daran, die Faktentabelle hat auch Schlüssel für Geographie, Förderung, Verkäufer , Etc.) Also, wenn die quotIndex Seekquot und quotHash Matchquot Zeile für Zeile arbeiten, tun sie dies über Werte, die möglicherweise in vielen anderen Zeilen wiederholt werden. Dies ist normalerweise, wo I39d segue zum SQL Server-Columnstore-Index, die ein Szenario bietet, um die Leistung dieser Abfrage auf erstaunliche Weise zu verbessern. Aber bevor ich das mache, gehen wir zurück in die Zeit. Let39s gehen zurück auf das Jahr 2010, als Microsoft ein Add-In für Excel als PowerPivot bekannt eingeführt. Viele Menschen erinnern sich wahrscheinlich daran, Demos von PowerPivot für Excel zu sehen, wo ein Benutzer Millionen von Zeilen aus einer externen Datenquelle in Excel lesen konnte. PowerPivot würde die Daten komprimieren und eine Engine bereitstellen, um Pivot-Tabellen und Pivot-Charts zu erstellen, die mit erstaunlichen Geschwindigkeiten gegen die komprimierten Daten durchgeführt wurden. PowerPivot benutzte eine In-Memory-Technologie, die Microsoft als "tertiPaqquot" bezeichnet. Diese In-Memory-Technologie in PowerPivot würde im Grunde genommen duplicate business keyforeign Schlüsselwerte und komprimieren sie bis zu einem einzigen Vektor. Die In-Memory-Technologie würde auch scanaggregate diese Werte parallel, in Blöcken von mehreren hundert zu einer Zeit. Die Quintessenz ist, dass Microsoft eine große Menge an Leistungsverbesserungen in die VertiPaq In-Memory-Funktion für uns zu verwenden, direkt aus der sprichwörtlichen Box gebacken. Warum bin ich unter diesem kleinen Spaziergang Speicher Lane Da in SQL Server 2012 implementiert eine der wichtigsten Funktionen in der Geschichte ihrer Datenbank-Engine: der Columnstore-Index. Der Index ist wirklich ein Index im Namen nur: es ist eine Weise, eine SQL-Server-Tabelle zu nehmen und ein komprimiertes, im Speicher befindliches columnstore zu verursachen, das doppelte Fremdschlüsselwerte bis Einzelvektorwerte komprimiert. Microsoft hat auch einen neuen Pufferpool erstellt, um diese komprimierten Vektorwerte parallel zu lesen und so das Potenzial für große Leistungssteigerungen zu schaffen. So, I39m gehen, um einen columnstore Index auf der Tabelle zu verursachen, und I39ll sehen, wie viel besser (und leistungsfähiger) die Abfrage, gegen die Abfrage, die gegen den bedeckenden Index läuft. So, I39ll erstellen Sie eine doppelte Kopie von FactOnlineSales (I39ll nennen es FactOnlineSalesDetailNCCS), und I39ll erstellen Sie einen columnstore-Index auf der duplizierten Tabelle, die Weise I won39t stören die ursprüngliche Tabelle und die Deckung Index in keiner Weise. Als nächstes erstellen wir einen Columnstore-Index für die neue Tabelle: Beachten Sie mehrere Dinge: I39ve hat mehrere Fremdschlüsselspalten sowie den Verkaufsbetrag angegeben. Denken Sie daran, dass ein columnstore-Index nicht wie ein herkömmlicher Zeilenspeicherindex ist. Es gibt keine Quotechart. Wir sind nur darauf hin, welche Spalten SQL Server komprimieren und platzieren sollte in einem in-memory columnstore. Um die Analogie von PowerPivot für Excel zu verwenden, wenn wir einen columnstore-Index erstellen, sagen wir SQL Server im Wesentlichen dasselbe, was PowerPivot tat, wenn wir 20 Millionen Zeilen in Excel mit PowerPivot importierten So I39ll erneut ausführen die Abfrage, diesmal mit Die doppelte FactOnlineSalesDetailNCCS-Tabelle, die den columnstore-Index enthält. Diese Abfrage läuft sofort in weniger als einer Sekunde. Und ich kann auch sagen, dass auch wenn der Tisch Hunderte von Millionen von Zeilen hatte, würde es immer noch auf das sprichwörtliche Quotbat eines Wimpernschuhs laufen. Wir könnten den Ausführungsplan (und in ein paar Momenten, wir werden), aber jetzt ist es Zeit, um die Abfrage Store-Feature zu decken. Stellen Sie sich für einen Moment vor, dass wir beide Abfragen über Nacht liefen: die Abfrage, die die reguläre FactOnlineSales-Tabelle (mit dem Deckungsindex) verwendete, und dann die Abfrage, die die doppelte Tabelle mit dem Columnstore-Index verwendete. Wenn wir uns am nächsten Morgen anmelden, sehen wir den Ausführungsplan für beide Abfragen, wie sie stattfanden, ebenso wie die Ausführungsstatistiken. Mit anderen Worten, wir sehen gerne die gleichen Statistiken, die wir in der Lage zu sehen, wenn wir beide Abfragen interaktiv in SQL Management Studio, in TIME und IO Statistiken gedreht und sah den Ausführungsplan direkt nach der Ausführung der Abfrage. Nun, that39s, was der Query Store ermöglicht es uns zu tun, können wir aktivieren (aktivieren) Abfrage-Speicher für eine Datenbank, die SQL Server auslösen wird, um Abfrage Ausführung speichern und planen Statistiken, so dass wir sie später anzeigen können. So, I39m gehen, um den Query Store auf der Contoso-Datenbank mit dem folgenden Befehl zu aktivieren (und I39ll auch löschen jedes Caching): Dann I39ll führen Sie die beiden Abfragen (und quotpretendquot, dass ich lief sie vor Stunden): Jetzt let39s vorgeben, dass sie lief Stunden vor. Nach dem, was ich sagte, wird der Query Store erfassen die Ausführungsstatistik. Also, wie kann ich sie ansehen Glücklicherweise ist das ziemlich einfach. Wenn ich die Contoso DW Datenbank erweitere, sehe ich einen Query Store Ordner. Der Abfrage-Speicher hat enorme Funktionalität und I39ll versuchen, viel von ihm in den folgenden Blogbeiträgen zu umfassen. Aber für jetzt, Ich möchte Ausführungsstatistiken auf die beiden Abfragen anzeigen, und speziell untersuchen die Ausführungsoperatoren für den columnstore-Index. So I39ll mit der rechten Maustaste auf die Top Resource Consuming Abfragen und führen Sie diese Option. Das gibt mir ein Diagramm wie das unten, wo kann ich sehen, Ausführungsdauer Zeit (in Millisekunden) für alle Abfragen, die ausgeführt wurden. In diesem Fall war Query 1 die Abfrage für die ursprüngliche Tabelle mit dem Deckungsindex und Query 2 für die Tabelle mit dem columnstore-Index. Die Zahlen don39t liegen der columnstore Index übertraf den ursprünglichen Tablecovering Index um einen Faktor von fast 7 zu 1. Ich kann die Metrik ändern, um Speicherverbrauch anstatt zu betrachten. In diesem Fall beachten Sie, dass Abfrage 2 (die Spalte-Index-Abfrage) viel mehr Speicher verwendet. Dies veranschaulicht, warum der columnstore-Index die Technologie von quotin-memoryquot darstellt. SQL Server lädt den gesamten columnstore-Index im Speicher und verwendet einen vollständig anderen Pufferpool mit erweiterten Ausführungsoperatoren, um den Index zu verarbeiten. Wenn Sie auf die vertikale Leiste für die Abfrage klicken, die den columnstore-Index verwendet hat, sehen Sie die Ausführung. Wenn Sie auf die vertikale Leiste klicken, werden die Ausführungsstatistiken angezeigt Plan unten. Das erste, was wir sehen, ist, dass SQL Server eine Columnstore-Index-Scan durchgeführt, und dass fast 100 der Kosten der Abfrage dargestellt. Sie könnten sagen, quotWait eine Minute, die erste Abfrage verwendet eine Deckung Index und führte eine Index-Suchvorgang, so wie kann ein columnstore Index-Scan fasterquot That39s eine legitime Frage, und glücklicherweise there39s eine Antwort. Selbst wenn die erste Abfrage eine Indexsuche durchführte, führte sie immer noch das Byte durch rowquot aus. Wenn ich die Maus über den columnstore index scan operator setze, sehe ich eine tooltip (wie die unten unten) mit einer wichtigen Einstellung: der Execution Mode ist BATCH (im Gegensatz zu ROW, was wir mit der ersten Abfrage hatten Deckungsindex). Dieser BATCH-Modus teilt mit, dass SQL Server die komprimierten Vektoren (für alle Fremdschlüsselwerte, die dupliziert werden, z. B. Product Key und Datumsschlüssel) in Chargen von fast 1.000 parallel verarbeitet werden. So ist SQL Server noch in der Lage, den columnstore Index viel effizienter zu verarbeiten. Darüber hinaus, wenn ich die Maus über die Hash Match (Aggregate) Task platzieren, sehe ich auch, dass SQL Server Aggregation der columnstore Index mithilfe Batch-Modus (obwohl der Operator selbst stellt so ein winziges Prozent der Kosten der Abfrage) Schließlich, Sie SQL-Server komprimiert die Werte in den Daten, behandelt die Werte als Vektoren, und lesen Sie sie in Blöcken von fast tausend Werte parallel, aber meine Abfrage wollte nur Daten für 2009. So ist SQL Server Scannen über die Gesamte Menge von Datenquot Wieder eine gute Frage. Die Antwort lautet: Nein. Zum Glück für uns führt der neue columnstore Index Pufferpool eine weitere Funktion namens segmentsegment eliminationquot aus. Grundsätzlich untersucht SQL Server die Vektorwerte für die Datumschlüsselspalte im columnstore-Index und eliminiert Segmente, die außerhalb des Geltungsbereichs des Jahres 2009 liegen. In nachfolgenden Blog-Posts I39ll decken sowohl die columnstore Index und Query Store in mehr Details. Im Wesentlichen, was wir hier gesehen haben, ist, dass der Columnstore-Index erheblich beschleunigt Abfragen, die scanaggregate über große Mengen an Daten, und der Query Store wird Abfrageausführungen erfassen und erlauben uns, Ausführungs-und Performance-Statistiken später zu untersuchen. Am Ende wollen wir eine Ergebnismenge erzeugen, die folgendes zeigt. Beachten Sie drei Dinge: Die Spalten schwenken im Wesentlichen alle möglichen Rückgabegründe, nachdem die Verkaufsmenge angezeigt wurde. Die Ergebnismenge enthält Zwischensummen für das Wochenende (Sonntag) über alle Clients (wobei der Client NULL ist) Die Ergebnismenge enthält eine Gesamtsumme Zeile (wo der Client und das Datum sind beide NULL) Zuerst, bevor ich in das SQL-Ende konnten wir die dynamische Pivotmatrix-Fähigkeit in SSRS verwenden. Wir müssten einfach die beiden Ergebnismengen um eine Spalte kombinieren und dann könnten wir die Ergebnisse an die SSRS-Matrix-Steuerung liefern, die die Rückkehrgründe über die Spaltenachse des Berichts verbreiten wird. Jedoch nicht jeder benutzt SSRS (obwohl die meisten Leute sollten). Aber selbst dann, manchmal Entwickler müssen Ergebnismengen in etwas anderes als ein Berichtswesen zu konsumieren. Also für dieses Beispiel nehmen wir an, wir wollen die Ergebnismenge für eine Web-Grid-Seite zu generieren und möglicherweise der Entwickler will outstot outquot die Zwischensumme Zeilen (wo ich habe einen ResultSetNum Wert von 2 und 3) und legen Sie sie in einem Summary Grid. So unten Zeile, müssen wir die Ausgabe oben direkt aus einer gespeicherten Prozedur zu generieren. Und als addierte Torsion nächste Woche konnte es Rückholgrund X und Y und Z geben. So wissen wir nicht, wie viele Rückholgründe es sein konnten. Wir wollen einfach, dass die Abfrage auf die möglichen unterschiedlichen Werte für Rückgabegrund verschoben wird. Hier ist, wo die T-SQL PIVOT eine Beschränkung, die wir brauchen, um es die möglichen Werte bieten. Da wir nicht wissen, dass bis zur Laufzeit, müssen wir die Abfrage-String dynamisch mit dem dynamischen SQL-Muster zu generieren. Das dynamische SQL-Muster beinhaltet die Erzeugung der Syntax, Stück für Stück, das Speichern in einem String und dann das Ausführen der Zeichenfolge am Ende. Dynamic SQL kann schwierig sein, da wir Syntax innerhalb einer Zeichenfolge einbetten müssen. Aber in diesem Fall ist es unsere einzige wahre Option, wenn wir eine variable Anzahl von Rückgabegründen behandeln wollen. Ich habe immer festgestellt, dass der beste Weg, um eine dynamische SQL-Lösung zu schaffen ist, indem Sie herausfinden, was die quotidealquot generierte-Abfrage am Ende sein würde (in diesem Fall angesichts der Rückkehr Gründen, die wir kennen) und dann reverse-Engineering es durch Piecing Es zusammen ein Teil zu einer Zeit. Und so, hier ist die SQL, die wir brauchen, wenn wir wussten, dass diese Rückkehr Gründe (A bis D) waren statisch und würde sich nicht ändern. Die Abfrage funktioniert folgendermaßen: Kombiniert die Daten von SalesData mit den Daten von ReturnData, wobei wir das Wort Sales als Aktionstyp für die Sales-Tabelle quothard-wirequot verwenden und dann die Rückgabe-Begründung aus den Rückgabedaten in dieselbe ActionType-Spalte verwenden. Das gibt uns eine saubere ActionType-Spalte, auf der wir drehen können. Wir kombinieren die beiden SELECT-Anweisungen zu einem gemeinsamen Tabellenausdruck (CTE), der im Grunde genommen eine abgeleitete Tabellenunterabfrage ist, die wir anschließend in der nächsten Anweisung (zu PIVOT) verwenden. Eine PIVOT-Anweisung gegen den CTE, die die Dollar für den Aktionstyp summiert Der sich in einem der möglichen Aktionsart-Werte befindet. Beachten Sie, dass dies nicht die endgültige Ergebnismenge ist. Wir setzen dies in einen CTE, der aus dem ersten CTE liest. Der Grund dafür ist, dass wir am Ende mehrere Gruppierungen durchführen wollen. Die letzte SELECT-Anweisung, die aus der PIVOTCTE liest, kombiniert sie mit einer nachfolgenden Abfrage desselben PIVOTCTE, wobei wir aber auch zwei Gruppierungen in der GROUPING SETS-Funktion in SQL 2008 implementieren: GROUPING am Wochenenddatum (dbo. WeekEndingDate) GROUPING für alle Zeilen () Wenn wir also mit Sicherheit wussten, dass wir nie mehr Rückgabecodes haben, dann wäre das die Lösung. Wir müssen aber auch andere Ursachencodes berücksichtigen. Also müssen wir diese ganze Abfrage oben als eine große Zeichenfolge generieren, wo wir die möglichen Rückkehrgründe als eine durch Kommas getrennte Liste konstruieren. I39m zu zeigen, den gesamten T-SQL-Code zu generieren (und auszuführen) der gewünschten Abfrage. Und dann breche ich es in Teile und erkläre jeden Schritt. So zuerst, hier39s der gesamte Code, um dynamisch zu erzeugen, was I39ve oben erhielt. Es gibt im Grunde fünf Schritte, die wir abdecken müssen. Schritt 1 . Wir wissen, dass irgendwo in der Mischung, müssen wir einen String für diese in der Abfrage zu generieren: SalesAmount, Grund A, Grund B, Grund C, Grund D0160016001600160 Was wir tun können, ist ein temporärer gemeinsamer Tabellenausdruck, der die harte verdrahtete quotSales kombiniert Amountquot-Spalte mit der eindeutigen Liste der möglichen Ursachencodes. Sobald wir das in einem CTE haben, können wir den schönen kleinen Trick von FOR XML PATH (3939) verwenden, um diese Zeilen zu einem einzelnen String zusammenzubrechen, ein Komma vor jeder Zeile zu setzen, die die Abfrage liest und dann STUFF zu ersetzen Die erste Instanz eines Kommas mit einem leeren Raum. Dies ist ein Trick, den Sie in Hunderten von SQL-Blogs finden können. Also dieser erste Teil baut eine Zeichenfolge namens ActionString, die wir weiter unten verwenden können. Schritt 2 . Wissen wir auch, dass wir39ll die generierten geneigten Grundspalten summieren wollen, zusammen mit der Standard-Verkaufsspalte. Also brauchen wir eine separate Zeichenfolge dafür, die ich SUMSTRING nennen werde. I39ll verwenden Sie einfach die ursprüngliche ActionString, und dann REPLACE die äußeren Klammern mit SUM-Syntax, plus die ursprünglichen Klammern. Schritt 3: Jetzt beginnt die eigentliche Arbeit. Mit dieser ursprünglichen Abfrage als Modell wollen wir die ursprüngliche Abfrage (beginnend mit der UNION der beiden Tabellen) generieren, aber alle Referenzen auf verschwenkte Spalten durch die dynamisch erzeugten Strings ersetzen. Auch wenn nicht unbedingt erforderlich, hat I39ve auch eine Variable erstellt, um einfach alle Wagenrücklauf-Feedkombinationen, die wir in die generierte Abfrage einbetten möchten (zur Lesbarkeit). So konstruieren wir die gesamte Abfrage in einer Variablen namens SQLPivotQuery. Schritt 4. Wir konstruieren die Abfrage erneut und verketten die Syntax, die wir mit dem ActionSelectString quothard-wirequot verknüpfen können (die wir dynamisch erzeugt haben, um alle möglichen Rückgabewerte zu halten) Schritt 5. Schließlich erzeugen wir den letzten Teil der Pivot-Abfrage, der aus dem 2. gemeinsamen Tabellenausdruck (PIVOTCTE, aus dem obigen Modell) liest und das letzte SELECT aus dem PIVOTCTE ausliest und es mit einem zweiten gegen PIVOTCTE lesen liest Implementieren die Gruppierungssätze. Schließlich können wir quotexecutequot die Zeichenfolge mit dem SQL-System gespeicherte proc spexecuteSQL So hoffentlich können Sie sehen, dass der Prozess für die folgenden für diese Art von Aufwand ist Bestimmen, was die endgültige Abfrage würde, basierend auf Ihren aktuellen Satz von Daten und Werten (dh gebaut werden Ein Abfragemodell) Schreiben Sie den erforderlichen T-SQL-Code, um dieses Abfragemodell als String zu generieren. Der wichtigste Teil ist die Bestimmung der einzigartigen Satz von Werten, auf denen Sie39ll PIVOT, und dann kollabieren sie in einen String mit der STUFF-Funktion und die FOR XML PATH (3939) Trick Also, was ist auf meinem Kopf heute Nun, mindestens 13 Elemente Zwei Summers, schrieb ich einen Entwurf des BDR, der sich (teilweise) auf die Rolle der Bildung und den Wert einer guten liberalen Kunst Hintergrund nicht nur für die Software-Industrie, sondern auch für andere Branchen als auch konzentriert. Eines der Themen dieser besonderen BDR betonte eine zentrale und erleuchtete Sichtweise des renommierten Softwarearchitekten Allen Holub über die freien Künste. Kranke (treu) paraphrasieren seine Botschaft: Er hebt die Parallelen zwischen Programmierung und Studium der Geschichte hervor, indem er alle daran erinnert, dass Geschichte Lesen und Schreiben ist (und Ill hinzufügen, Muster identifizieren), und Software-Entwicklung ist auch Lesen und Schreiben (und wieder Identifizierung von Mustern ). Und so schrieb ich eine Stellungnahme Stück, das auf diesem und anderen verwandten Themen konzentriert. Aber bis heute habe ich nie zu veröffentlichen. Jeder so oft Id denken der Überarbeitung, und Id sogar sitzen für ein paar Minuten und machen einige Anpassungen an sie. Aber dann würde das Leben im Allgemeinen im Weg und Id nie beenden. So was geändert Vor ein paar Wochen, CoDe Magazin Kolumnist und Branchenführer Ted Neward schrieb ein Stück in seiner regulären Spalte, Managed Coder, die meine Aufmerksamkeit erregte. Der Titel des Artikels ist On Liberal Arts. Und ich empfehle, dass alle es lesen. Ted diskutiert den Wert eines liberalen Kunsthintergrundes, die falsche Dichotomie zwischen einem liberalen Kunsthintergrund und Erfolg in der Software-Entwicklung und die Notwendigkeit, writecommunicate gut zu schreiben. Er spricht über einige seiner eigenen vergangenen Begegnungen mit HR Personalmanagement in Bezug auf seinen pädagogischen Hintergrund. Darüber hinaus unterstreicht er die Notwendigkeit, Veränderungen in unserer Branche zu akzeptieren und anzupassen, sowie die Kennzeichen eines erfolgreichen Softwareprofis (zuverlässig, vorausschauend und lernen, anfangs Konflikte mit anderen Teammitgliedern zu erlernen). Also seine eine große lesen, wie sind Teds andere CoDe Artikel und Blog-Einträge. Es hat auch mich zurück zu denken über meine Ansichten zu diesem (und anderen Themen) als auch, und schließlich motiviert mich, meine eigene Redaktion zu beenden. Also, besser spät als nie, hier sind meine aktuellen Bakers Dozen of Reflections: Ich habe ein Sprichwort: Wasser friert bei 32 Grad. Wenn youre in einer Trainingsrolle Rolle, könnten Sie denken, dass Sie alles in der Welt tun, um jemanden zu helfen, wenn in der Tat, theyre nur das Gefühl einer Temperatur von 34 Grad und daher Dinge, die Arent erstarrt für sie. Manchmal dauert es nur ein wenig mehr Aufwand oder einen anderen ideachemischen Katalysator oder eine neue Perspektive, was bedeutet, dass diejenigen mit vorheriger Ausbildung auf verschiedene Quellen zurückgreifen können. Wasser friert bei 32 Grad. Einige Leute können ein hohes Maß an Konzentration auch mit einem Raum voller lärmender Menschen zu halten. Im nicht einer von ihnen gelegentlich brauche ich etwas Privatleben, zum durch ein kritisches Problem zu denken. Manche Leute beschreiben dies, wie Sie gotta lernen zu gehen weg von ihm. Anders gesagt, seine Suche nach der verdünnten Luft. In der vergangenen Woche verbrachte ich Stunden in einem halbbeleuchteten, ruhigen Raum mit einem Whiteboard, bis ich ein Problem völlig verstand. Erst dann konnte ich mit anderen Entwicklern über eine Lösung sprechen. Die Botschaft hier ist nicht zu predigen, wie Sie über Ihr Geschäft der Lösung von Problemen gehen sollten, sondern für alle, ihre Stärken kennen und was funktioniert, und verwenden Sie sie zu Ihrem Vorteil so viel wie möglich. Einige Phrasen sind wie Fingernägel auf einer Tafel für mich. Verwenden Sie es als Lehre Moment ist eins. (Warum ist es wie Fingernägel auf einer Tafel Weil, wenn youre in einer Mentoring-Rolle, sollten Sie in der Regel im Unterricht Moment-Modus sowieso, aber subtil). Heres ein anderes ich kann nicht wirklich erklären es in den Wörtern, aber ich verstehe es. Das klingt ein bisschen kalt, aber wenn eine Person wirklich kann nicht erklären, etwas in Worten, vielleicht sie nicht verstehen. Sicher, kann eine Person ein Fuzzy-Gefühl, wie etwas funktioniert, kann ich bluffen mein Weg durch die Beschreibung, wie eine Digitalkamera funktioniert, aber die Wahrheit ist, dass ich nicht wirklich verstehen, alles, was gut. Es gibt ein Fachgebiet, das als Erkenntnistheorie (das Studium des Wissens) bekannt ist. Eine der grundlegenden Grundlagen des Verständnisses, ob es sich um eine Kamera oder ein Designmuster handelt, ist die Fähigkeit, Kontext zu ermitteln, die Kette der verwandten Ereignisse zu identifizieren, die Attribute aller Komponenten auf dem Weg usw. Ja, das Verstehen ist manchmal sehr harte Arbeit , Aber Tauchen in ein Thema und brechen es auseinander ist die Mühe wert. Auch diejenigen, die Zertifizierung nicht anerkennen, wird anerkennen, dass der Prozess des Studiums für Zertifizierungstests wird dazu beitragen, Lücken in Wissen zu füllen. Ein Datenbank-Manager ist eher ein Datenbank-Entwickler, der sprechen kann extemporally (und mühelos) über Transaktions-Isolation Ebenen und Trigger, im Gegensatz zu jemandem, der Art weiß, aber kämpft, um ihre Verwendung zu beschreiben. Theres ein anderes Korrespondent hier. Ted Neward empfiehlt, dass Entwickler öffentlich zu sprechen, zu bloggen, etc. Ich stimme 100. Der Prozess der öffentlichen Reden und Bloggen wird praktisch zwingen Sie sich Gedanken über Themen und brechen Definitionen, die Sie sonst für selbstverständlich gehalten haben könnte. Vor ein paar Jahren dachte ich, ich verstand die T-SQL MERGE-Anweisung ziemlich gut. Aber nur, nachdem ich darüber geschrieben und darüber gesprochen hatte, Fragen von anderen gestellt, die Perspektiven hatten, die mir nie einfielen, dass meine Ebene des Verstehens exponentiell zunahm. Ich kenne eine Geschichte von einem Personalchef, der einmal ein Autorentwickler für eine Vertragsposition interviewte. Der Vermieter war verächtlich von Publikationen im Allgemeinen, und bellte an der Klägerin, Also, wenn youre gehen, hier zu arbeiten, würden Sie lieber Bücher schreiben oder schreiben Code Ja, Ill gewähren, dass in jeder Branche gibt es ein paar reine Wissenschaftler werden. Aber was der Vermieter vermisst, war die Möglichkeiten zur Stärkung und Schärfung von Fertigkeiten. Beim Reinigen einer alten Schachtel Bücher, stieß ich auf einen Schatz aus den 1980er Jahren: Programmers at Work. Die Interviews mit einem sehr jungen Bill Gates, Ray Ozzie, und andere bekannte Namen enthält. Jedes Interview und jede Einsicht ist den Preis des Buches wert. Meiner Ansicht nach war das interessanteste Gespräch mit Butler Lampson. Der einige mächtige Ratschläge gab. Zum Teufel mit Computerkenntnissen. Es ist absolut lächerlich. Studieren Mathematik. Denken lernen. Lesen. Schreiben. Diese Dinge sind von dauerhafterem Wert. Lernen Sie, wie man die Theoreme beweisen: Viele Beweise haben sich über die Jahrhunderte angesammelt, die darauf schließen lassen, dass diese Fähigkeit auf viele andere Dinge übertragbar ist. Butler spricht die Wahrheit. Kranke addiere zu diesem Punkt erlernen, wie man Teufel gegen sich selbst befürwortet. Je mehr Sie Realität-überprüfen Sie Ihre eigenen Prozesse und arbeiten können, desto besser werden youll werden. Der große Informatiker Allen Holub machte die Verbindung zwischen Softwareentwicklung und den freien Künsten speziell, dem Thema der Geschichte. Hier war sein Punkt: Was ist Geschichte Lesen und Schreiben. Was ist Software-Entwicklung Unter anderem, Lesen und Schreiben. Ich habe zu geben, meine Studenten T-SQL Essay Fragen als Praxis-Tests. Ein Schüler scherzte, dass ich mehr wie ein Gesetzesprofessor handelte. Nun, genau wie Trainer Donny Haskins sagte im Film Glory Road, ist mein Weg schwer. Ich glaube fest an eine starke intellektuelle Grundlage für jeden Beruf. Genau wie Anwendungen können von Frameworks profitieren, können Einzelpersonen und ihre Denkprozesse von menschlichen Rahmenbedingungen profitieren als gut. Das ist die fundamentale Grundlage der Stipendien. Es gibt eine Geschichte, die in den 1970er Jahren, IBM erweitert ihre Recruiting-Anstrengungen in den großen Universitäten durch die Konzentration auf die besten und hellsten der liberal arts Absolventen. Sogar dann erkannten sie, daß die besten Leser und Verfasser eines Tages ein starkes Programmersystemanalytiker werden konnten. (Fühlen Sie sich frei, diese Geschichte zu jeder HR-Typ, der darauf besteht, dass ein Kandidat muss ein Informatik-Abschluss sein, besteht) Und Sprechen der Geschichte: Wenn aus keinem anderen Grund ist es wichtig, die Geschichte der Produktfreigaben erinnern, wenn ich arbeite bei einem Client-Website, die noch mit SQL Server 2008 oder sogar (Gasp) SQL Server 2005, ich habe zu erinnern, welche Funktionen in den Versionen im Laufe der Zeit implementiert wurden. Haben Sie jemals einen Lieblingsarzt, den Sie mochten, weil heshe erklärte Sachen in einfachem Englisch, gab Ihnen die gerade Wahrheit und verdiente Ihr Vertrauen, um auf Ihnen zu arbeiten. Das sind wütende Fähigkeiten. Und sind das Ergebnis der Erfahrung und harte Arbeit, die Jahre und sogar Jahrzehnte zu kultivieren. Es gibt keine Garantien der Job-Erfolg konzentrieren sich auf die Fakten, nehmen ein paar kalkulierte Risiken, wenn Sie sicher, dass Sie Ihren Weg in die Ziellinie sehen können, lassen Sie die Chips fallen, wo sie können, und nie aus den Augen verlieren, gerade wie der Arzt, der verdiente Dein Vertrauen. Obwohl einige Tage ich untergekommen bin, versuche ich, meinen Klienten und ihre Daten zu behandeln, wie ein Doktor Patienten behandeln würde. Obwohl ein Arzt mehr Geld macht Es gibt viele Klischees, die ich verabscheue, aber Heres eins, das ich nicht hasse: Es gibt keine solche Sache wie eine schlechte Frage. Als ehemaliger Lehrer, eine Sache, die mein Zorn zog, war zu hören jemand kritisieren eine andere Person für die Frage einer angeblich, dumme Frage. Eine Frage bedeutet, eine Person erkennt, dass sie eine gewisse Lücke im Wissen, die sie suchen zu füllen. Ja, einige Fragen sind besser formuliert als andere, und einige Fragen erfordern zusätzliche Framing, bevor sie beantwortet werden können. Aber die Reise von der Bildung einer Frage zu einer Antwort ist wahrscheinlich, einen aktiven geistigen Prozess in anderen zu erzeugen. Es gibt alle guten Dinge. Viele gute und fruchtbare Diskussionen stammen von einer dummen Frage. Ich arbeite auf der ganzen Linie in SSIS, SSAS, SSRS, MDX, PPS, SharePoint, Power BI, DAX alle Werkzeuge im Microsoft BI-Stack. Ich schreibe immer noch einige. NET-Code von Zeit zu Zeit. Aber erraten, was ich noch so viel Zeit damit verbringen, T-SQL-Code zu Profildaten als Teil des Entdeckungsprozesses zu schreiben. Alle Anwendungsentwickler sollten gute T-SQL-Chops haben. Ted Neward schreibt (richtig) über die Notwendigkeit, sich an technologische Veränderungen anzupassen. Ich füge hinzu, dass die Notwendigkeit, an Clientemployer Änderungen anzupassen. Unternehmen ändern Geschäftsregeln. Unternehmen erwerben andere Unternehmen (oder werden das Ziel einer Akquisition). Unternehmen machen Fehler bei der Kommunikation von Geschäftsanforderungen und Spezifikationen. Ja, wir können manchmal eine Rolle bei der Verwaltung dieser Veränderungen zu übernehmen und manchmal waren die Fliege, nicht die Windschutzscheibe. Diese verursachen manchmal große Schmerzen für alle, vor allem die I. T. Menschen. Deshalb ist der Begriff Tatsache des Lebens existiert, müssen wir damit umgehen. Genau wie kein Entwickler schreibt fehlerfreien Code jedes Mal, keine I. T. Person befasst sich mit Veränderung jeder einzelnen Zeit. Einer der größten Kämpfe, die Ive in meinen 28 Jahren in dieser Industrie gehabt hat, zeigt Geduld und Zurückhaltung, wenn Änderungen von vielen verschiedenen Richtungen fliegen. Hier ist, wo mein vorheriger Vorschlag über die Suche nach der rarified Luft helfen kann. Wenn Sie es schaffen, Veränderungen in Ihren Gedanken Prozess zu assimilieren, und ohne Gefühl überwältigt, sind Chancen youll ein bedeutender Vermögenswert. In den letzten 15 Monaten musste Ive mit einer riesigen Menge an professionellem Wandel umgehen. Sein gewesen sehr schwieriges manchmal, aber Ive beschlossen, dass Änderung die Norm ist und Ive versuchte, meine eigenen Gewohnheiten so gut zu justieren, dass ich mit häufiger (und unsicherer) Änderung fertig werden kann. Seine harte, sehr hart. Aber als Trainer Jimmy Duggan sagte in dem Film Eine Liga ihrer eigenen: Natürlich ist es schwer. Wenn es nicht hart war, würde jeder es tun. Das harte, ist, was es groß macht. Eine kraftvolle Botschaft. In den letzten Jahren wurde in der Industrie über das Verhalten bei Berufskonferenzen (und in der Industrie insgesamt) gesprochen. Viele angesehene Schriftsteller haben sehr gute Leitartikel zum Thema geschrieben. Heres meine Eingabe, für was seinen Wert. Its a message to those individuals who have chosen to behave badly: Dude, it shouldnt be that hard to behave like an adult. A few years ago, CoDe Magazine Chief Editor Rod Paddock made some great points in an editorial about Codes of Conduct at conferences. Its definitely unfortunate to have to remind people of what they should expect out of themselves. But the problems go deeper. A few years ago I sat on a five-person panel (3 women, 2 men) at a community event on Women in Technology. The other male stated that men succeed in this industry because the Y chromosome gives men an advantage in areas of performance. The individual who made these remarks is a highly respected technology expert, and not some bozo making dongle remarks at a conference or sponsoring a programming contest where first prize is a date with a bikini model. Our world is becoming increasingly polarized (just watch the news for five minutes), sadly with emotion often winning over reason. Even in our industry, recently I heard someone in a position of responsibility bash software tool XYZ based on a ridiculous premise and then give false praise to a competing tool. So many opinions, so many arguments, but heres the key: before taking a stand, do your homework and get the facts . Sometimes both sides are partly rightor wrong. Theres only one way to determine: get the facts. As Robert Heinlein wrote, Facts are your single clue get the facts Of course, once you get the facts, the next step is to express them in a meaningful and even compelling way. Theres nothing wrong with using some emotion in an intellectual debate but it IS wrong to replace an intellectual debate with emotion and false agenda. A while back I faced resistance to SQL Server Analysis Services from someone who claimed the tool couldnt do feature XYZ. The specifics of XYZ dont matter here. I spent about two hours that evening working up a demo to cogently demonstrate the original claim was false. In that example, it worked. I cant swear it will always work, but to me thats the only way. Im old enough to remember life at a teen in the 1970s. Back then, when a person lost hisher job, (often) it was because the person just wasnt cutting the mustard. Fast-forward to today: a sad fact of life is that even talented people are now losing their jobs because of the changing economic conditions. Theres never a full-proof method for immunity, but now more than ever its critical to provide a high level of what I call the Three Vs (value, versatility, and velocity) for your employerclients. I might not always like working weekends or very late at night to do the proverbial work of two people but then I remember there are folks out there who would give anything to be working at 1 AM at night to feed their families and pay their bills. Always be yourselfyour BEST self. Some people need inspiration from time to time. Heres mine: the great sports movie, Glory Road. If youve never watched it, and even if youre not a sports fan I can almost guarantee youll be moved like never before. And Ill close with this. If you need some major motivation, Ill refer to a story from 2006. Jason McElwain, a high school student with autism, came off the bench to score twenty points in a high school basketball game in Rochester New York. Heres a great YouTube video. His mother said it all . This is the first moment Jason has ever succeeded and is proud of himself. I look at autism as the Berlin Wall. He cracked it. To anyone who wanted to attend my session at todays SQL Saturday event in DC I apologize that the session had to be cancelled. I hate to make excuses, but a combination of getting back late from Detroit (client trip), a car thats dead (blown head gasket), and some sudden health issues with my wife have made it impossible for me to attend. Back in August, I did the same session (ColumnStore Index) for PASS as a webinar. You can go to this link to access the video (itll be streamed, as all PASS videos are streamed) The link does require that you fill out your name and email address, but thats it. And then you can watch the video. Feel free to contact me if you have questions, at kgoffkevinsgoff. net November 15, 2013 Getting started with Windows Azure and creating SQL Databases in the cloud can be a bit daunting, especially if youve never tried out any of Microsofts cloud offerings. Fortunately, Ive created a webcast to help people get started. This is an absolute beginners guide to creating SQL Databases under Windows Azure. It assumes zero prior knowledge of Azure. You can go to the BDBI Webcasts of this website and check out my webcast (dated 11102013). Or you can just download the webcast videos right here: here is part 1 and here is part 2. You can also download the slide deck here. November 03, 2013 Topic this week: SQL Server Snapshot Isolation Levels, added in SQL Server 2005. To this day, there are still many SQL developers, many good SQL developers who either arent aware of this feature, or havent had time to look at it. Hopefully this information will help. Companion webcast will be uploaded in the next day look for it in the BDBI Webcasts section of this blog. October 26, 2013 Im going to start a weekly post of T-SQL tips, covering many different versions of SQL Server over the years Heres a challenge many developers face. Ill whittle it down to a very simple example, but one where the pattern applies to many situations. Suppose you have a stored procedure that receives a single vendor ID and updates the freight for all orders with that vendor id. create procedure dbo. UpdateVendorOrders update Purchasing. PurchaseOrderHeader set Freight Freight 1 where VendorID VendorID Now, suppose we need to run this for a set of vendor IDs. Today we might run it for three vendors, tomorrow for five vendors, the next day for 100 vendors. We want to pass in the vendor IDs. If youve worked with SQL Server, you can probably guess where Im going with this. The big question is how do we pass a variable number of Vendor IDs Or, stated more generally, how do we pass an array, or a table of keys, to a procedure Something along the lines of exec dbo. UpdateVendorOrders SomeListOfVendors Over the years, developers have come up with different methods: Going all the way back to SQL Server 2000, developers might create a comma-separated list of vendor keys, and pass the CSV list as a varchar to the procedure. The procedure would shred the CSV varchar variable into a table variable and then join the PurchaseOrderHeader table to that table variable (to update the Freight for just those vendors in the table). I wrote about this in CoDe Magazine back in early 2005 (code-magazinearticleprint. aspxquickid0503071ampprintmodetrue. Tip 3) In SQL Server 2005, you could actually create an XML string of the vendor IDs, pass the XML string to the procedure, and then use XQUERY to shred the XML as a table variable. I also wrote about this in CoDe Magazine back in 2007 (code-magazinearticleprint. aspxquickid0703041ampprintmodetrue. Tip 12)Also, some developers will populate a temp table ahead of time, and then reference the temp table inside the procedure. All of these certainly work, and developers have had to use these techniques before because for years there was NO WAY to directly pass a table to a SQL Server stored procedure. Until SQL Server 2008 when Microsoft implemented the table type. This FINALLY allowed developers to pass an actual table of rows to a stored procedure. Now, it does require a few steps. We cant just pass any old table to a procedure. It has to be a pre-defined type (a template). So lets suppose we always want to pass a set of integer keys to different procedures. One day it might be a list of vendor keys. Next day it might be a list of customer keys. So we can create a generic table type of keys, one that can be instantiated for customer keys, vendor keys, etc. CREATE TYPE IntKeysTT AS TABLE ( IntKey int NOT NULL ) So Ive created a Table Typecalled IntKeysTT . Its defined to have one column an IntKey. Nowsuppose I want to load it with Vendors who have a Credit Rating of 1..and then take that list of Vendor keys and pass it to a procedure: DECLARE VendorList IntKeysTT INSERT INTO VendorList SELECT BusinessEntityID from Purchasing. Vendor WHERE CreditRating 1 So, I now have a table type variable not just any table variable, but a table type variable (that I populated the same way I would populate a normal table variable). Its in server memory (unless it needs to spill to tempDB) and is therefore private to the connectionprocess. OK, can I pass it to the stored procedure now Well, not yet we need to modify the procedure to receive a table type. Heres the code: create procedure dbo. UpdateVendorOrdersFromTT IntKeysTT IntKeysTT READONLY update Purchasing. PurchaseOrderHeader set Freight Freight 1 FROM Purchasing. PurchaseOrderHeader JOIN IntKeysTT TempVendorList ON PurchaseOrderHeader. VendorID Te mpVendorList. IntKey Notice how the procedure receives the IntKeysTT table type as a Table Type (again, not just a regular table, but a table type). It also receives it as a READONLY parameter. You CANNOT modify the contents of this table type inside the procedure. Usually you wont want to you simply want to read from it. Well, now you can reference the table type as a parameter and then utilize it in the JOIN statement, as you would any other table variable. So dort haben Sie es. A bit of work to set up the table type, but in my view, definitely worth it. Additionally, if you pass values from. NET, youre in luck. You can pass an ADO. NET data table (with the same tablename property as the name of the Table Type) to the procedure. For. NET developers who have had to pass CSV lists, XML strings, etc. to a procedure in the past, this is a huge benefit. Finally I want to talk about another approach people have used over the years. SQL Server Cursors. At the risk of sounding dogmatic, I strongly advise against Cursors, unless there is just no other way. Cursors are expensive operations in the server, For instance, someone might use a cursor approach and implement the solution this way: DECLARE VendorID int DECLARE dbcursor CURSOR FASTFORWARD FOR SELECT BusinessEntityID from Purchasing. Vendor where CreditRating 1 FETCH NEXT FROM dbcursor INTO VendorID WHILE FETCHSTATUS 0 EXEC dbo. UpdateVendorOrders VendorID FETCH NEXT FROM dbcursor INTO VendorID The best thing Ill say about this is that it works. And yes, getting something to work is a milestone. But getting something to work and getting something to work acceptably are two different things. Even if this process only takes 5-10 seconds to run, in those 5-10 seconds the cursor utilizes SQL Server resources quite heavily. Thats not a good idea in a large production environment. Additionally, the more the of rows in the cursor to fetch and the more the number of executions of the procedure, the slower it will be. When I ran both processes (the cursor approach and then the table type approach) against a small sampling of vendors (5 vendors), the processing times where 260 ms and 60 ms, respectively. So the table type approach was roughly 4 times faster. But then when I ran the 2 scenarios against a much larger of vendors (84 vendors), the different was staggering 6701 ms versus 207 ms, respectively. So the table type approach was roughly 32 times faster. Again, the CURSOR approach is definitely the least attractive approach. Even in SQL Server 2005, it would have been better to create a CSV list or an XML string (providing the number of keys could be stored in a scalar variable). But now that there is a Table Type feature in SQL Server 2008, you can achieve the objective with a feature thats more closely modeled to the way developers are thinking specifically, how do we pass a table to a procedure Now we have an answer Hope you find this feature help. Feel free to post a comment. Best Wine Coolers 038 Fridges 8211 (Reviews 038 Guide 2016) Without being a wine expert, most wine-lovers know that it is a delicate beverage. To enjoy the taste at its fullest, it should be carefully stored and served at a proper temperature. Before going into details about cooling techniques and wine refrigerator reviews . be sure that, you8217ll get all information to find the best wine cooler in this post For those who keep their wine bottles in the refrigerator, it takes up precious space which can be used for food instead. Also, a refrigerator is too cold and lacks the required humidity. Storing wine bottles in cupboards or cabinets, on the other hand, poses a greater risk on your wines fate, especially if your place is overheated or has changing temperature. A wine cooler is a perfect solution because it provides enough space and proper conditions to store wine. This way, you can be well prepared for a party or save a precious vintage for special occasions without the risk of spoiling it. Choosing the right wine cooler is difficult as there are many types and features. Still, you can select the best wine cooler according to your needs with the help of our wine cooler reviews below Top Rated Wine Coolers 4.3 Customer Rating Wine Enthusiast 6 Bottle Touchscreen Wine Cooler This 6-bottle capacity wine cooler is the right size for beginner wine enthusiasts. Its compact size allows you to place it on your countertop without taking up much space. The interior LED lighting, the reflective smoked-glass door and the designer style make it look more like a chic accessory on your counter. With an adjustable temperature range of 44-66F, you can set it to your desired temperature to store a couple of precious bottles to serve any day and to cool a few bottles of wine at a time. The exterior digital touchscreen with temperature display helps you control the temperature easily. As a thermoelectric cooler, Wine Enthusiast 6 Bottle Wine Cooler is energy-efficient and CFC-free. Thanks to its silent cooling technology, it protects the taste of your wine quietly. Also, you can easily fit the bottles on the 3 sturdy pull-out chrome shelves. If you are not sure if a wine cooler is worth a try, this compact, and affordable model will help introduce you to the experience. As you enjoy your wine more, you may see it is an excellent value for the price and you may even consider taking it one step further in the future. Avanti 12 Bottle Thermoelectric Counter Top Wine Cooler 8211 Model EWC1201 Due to its innovative design which allows vertical storage of 4 bottles, this wine cooler stands out among its peers. The vertical storage space can be used for opened bottles of wine. This way, you dont need to worry about finishing a whole bottle just because the wine will spoil once it is opened. Moreover, if you favor using vacuum stoppers for opened bottles, they will fit in perfectly in the cooler as you can place the bottles in an upright position. Also, the 8-bottle horizontal area of Avanti Wine Cooler provides adequate space to preserve your unopened bottles. Thanks to its compact design, Avanti 12 Bottle Wine Cooler doesnt take as much space for the amount of wine it holds. The curved glass door and the black cabinet add to its stylish looks and make it a nice to have piece of your decor, not just a cooler. With its innovative thermoelectric cooling technology, Avanti 12 Bottle Wine Cooler provides an ultra-quiet cooling environment and minimizes the vibration which is crucial not to disturb bottle sediment. The soft-touch temperature control switches have delayed control mechanism which prevents unwanted temperature changes by random pushes of children. In short, you can find smart looks and functionality in Avanti 12 Bottle Wine Cooler. Click here for our full-featured Avanti 12 Bottle Counter Top Review . Haier 12-Bottle Dual Zone Curved Door with Smoked Glass Wine Cellar Haier 12 Bottle Dual Zone Wine Cellar is the right choice if you love your chilled whites as much as your not-so-chilled reds. As a benefit of dual zone structure, you can adjust the temperature at 46-66F in the lower compartment for white wine whereas at 54-66F in the upper compartment for red. This way, you can store your white and red wine separately and serve them at their optimal temperature. Thanks to its thermoelectric cooling system, Haier 12 Bottle Dual Zone Wine Cellar is whisper-quiet, vibration-free and keeps the temperature steady even with fluctuations in the ambient temperature. With its slim design, the cooler unit has a small footprint so that you can place it even in little nooks. On the other hand, it is deep enough so that you can use vacuum seal corks and also have room up front for longer bottles. It has an attractive look with its style, the curved door with smoked glass and the interior LED light. If you are looking for an inexpensive, easy to operate and good looking dual zone wine cooler, Haier 12 Bottle Dual Zone Wine Cellar is a perfect choice. For the ones who like the features of Haier Wine Cooler but not sure about the size, it also comes in smaller and larger sizes. Whynter 20 Bottle Thermoelectric Wine Cooler Whynter Wine Cooler is as cool as it gets because it is true to its word of keeping the temperature at its lowest around 46F, regardless of the ambient temperature. The temperature can be adjusted precisely from the soft-touch digital control panel and stays consistent at the pre-set degree. The unit has a black tinted mirror glass door which is pleasing to the eye and also plays an important role in providing extra protection from UV rays that can affect the consistency of wine. The wine cooler has a soft interior LED lighting which enables you to see through the glass door into the cooler. Besides being useful, this light adds a nice glow and even functions as a sweet nightlight. Being a thermoelectric cooler, Whynter Wine Cooler is vibration-free, quiet and long lasting. The cabinet is deep enough to store taller bottles and the racks are light yet very stable. They dont come out when you pull a bottle out which is an advantage as it prevents any accidental losses. The unit has leveling legs, which is a plus among others. If you want to keep more than a few bottles and especially chilled whites, Whynter 20 Bottle Thermoelectric Wine Cooler is your type. With its functionality and sleek design, this cooler can make a sophisticated addition to your home. Explore more of this cooler8217s features with our comprehensive Whynter 20 Bottle review . NewAir AWR-460DB 46 Bottle Built-in Dual Zone Compressor You can be a beginning collector with many precious bottles or a connoisseur with years of experience, NewAir AWR-460DB will definitely meet your expectations with its advanced features and all-inclusive design. Thanks to its front venting system, this cooler is suitable for built-in use. Still, with its stainless steel elegant design, you can place it anywhere of your choice as a freestanding unit. Moreover, the reversible door gives you more freedom in where to place your cooler and the door lock keeps your wine safe from intruders. The dual zone structure enables you to conserve red and white wine in separate compartments with independent climate control and keep them at their optimum serving temperature. The adjustable wooden shelves provide a spacious and customizable interior that holds up to 46 bottles. NewAir AWR-460DB offers an adjustable temperature range of 40-66F so that you can set for long-term storage or ready to serve. The compressor cooling maintains even temperatures throughout the interior and you can adjust the temperature precisely from the digital control panel. The unit has a built-in carbon filter to prevent odors and a blue LED light that reflects a nice hue on your collection. If you are looking for a smaller wine cooler from NewAir, you might want to check 18 Bottle version. If you are looking for a high-quality wine cooler with good storage capacity and top-notch attributes, NewAir AWR-460DB is an excellent choice for you. How to Store Wine at Home The key to storing any wine at home is to keep heat away from it. It can range from 7 to 18 degrees centigrade, but 138217C is almost perfect. Anything higher than 21 8216C will age wine and eventually lose its characteristic flavors and aroma. Learn more about ideal wine temperatures and storing requirements. including the temperature ranges as represented in degrees Fahrenheit. How to Choose a Wine Cooler Aided in some part by direct publication channels such as YouTube, foodie blogs, and cheap domain names, the wine experience market as witnessed an explosion over the past few years. We purposefully call it a wine enthusiasts experience as opposed to a mere wine drinking market because there are so many dynamics surrounding wine these days. To the true wine enthusiast, the wine lovers experience goes beyond the process of popping a bottle of your favorite variety and enjoying a glass. The wine lovers experience today has evolved into a big part the quintessential wine enthusiasts lifestyle, with the help of accessories such as wine coolers. The wine cooler, in particular, has brought the entire wine enthusiasts experience into the wine lovers home, making it more affordable to store, display and chill some of their favorite bottles for optimal consumption. Wine coolers, in particular, are taking center-stage as perhaps the main supporting acts to the consumption of the actual wines themselves. Wine coolers in their many varieties are also becoming cheaper and cheaper, making them more and more accessible to a new creed of wine enthusiasts. Wine storage used to be a rather expensive exercise, with the typical wine connoisseur of days gone by having to fork out a hefty sum for a built-in wine cellar, usually housed on the basement floor of their house. The advent and explosively growing popularity and availability of wine coolers have bridged that gap between a big budget and a deep-running love for wine, giving just about every wine lover the opportunity to take their enthusiasm for wine to the next level and bring it right into their own space. But how does one go about selecting a wine cooler, though, particularly taking into account the ever-growing list of available options from just as many manufacturers Real wine enthusiasts whose love for wine has them seriously considering investing in a dedicated wine cooling device will at this point know that buying a wine cooler is in no way like buying a regular refrigerator . If it was ideal to store your wines in a standard home fridge, thered be no purpose-built wine cooling appliances like electric wine cellars, wine refrigerators, and wine coolers. The wine cooler you ultimately decide to invest in naturally has to complement all your wine storage and wine displaying needs, whether current or in the immediate to long-term future. It is with this consideration in mind that you should go about picking out the ideal wine cooler. These considerations can be broken down into a list of three (3) main pointers to consider, which can be further broken down to some specific variables and values that best suit your requirements. This consideration point is fairly straightforward, largely limited only by the options you have available to you. Fortunately, though these options are aplenty, giving you a lot of styles and tastes to choose from. Wine coolers are known to sport some of the best design work of the appliance manufacturing industry, from classic, sophisticated, chic, and elegant, right up to contemporary and even ultra-modern. In some cases, youll even have some futuristic (out-of-this-world) design standards to choose from. Chances are any wine cooler you choose to buy will have you and your fellow wine-loving guests looking at it more than once, so itll then ultimately come down to your own personal style in terms of design. Most wine coolers also sport designs which are purpose-made to either serve as the focal point of your interiors or to blend in very well with any interior decoration style. When design moves away from outward appearance and spills over into practicality, picking out a wine cooler relies on the features it packs. Specific features to look for include: Warranty Size (in volume and weight do you want portability or do you want to maybe replace an old trash compactor) Temperature range How it operates how do you monitor the temperature and how do you setchange the temperature settings Bottle capacity Interior illumination (are you satisfied with a light that makes the cooler look nice or do you want to be able to see the labels through the glass) Type of cooler used (compression or thermoelectric cooling) Number of cooling compartments (single or dual-zone cooling) Application (countertop, under-counter, or built-in cooler ) Functionality Finally, when browsing through wine coolers with the view of settling on one that best meets your needs, you have to consider the wine coolers functionality. This is done through looking at the features list and trying to translate that into a practical setting. In other words, what exactly will you be using it for and, with that in mind, which cooler has the widest range of features that coincide with what youll be using it for For example, if you want a versatile wine cooler in which you can store both your red and white wines, you might consider a dual-zone cooler with independent temperature cooling compartments that have respective temperature ranges. These independent cooling zones and their respective temperature ranges would then be optimal for the storage of the different wine varieties at temperatures best suited to them. Some of the consideration points are self-explanatory, like the bottle capacity and whether you want an under counter, countertop or freestanding cooler. With regards to the temperature range and which types of wine, youll want to store in your cooler, the cooling technology used (thermoelectric vs. compression cooling) plays an important role. If you want a bigger capacity cooler (24-24 bottles), you might have to settle for a compression-cooled unit, which isnt a bad thing because compression coolers are known to last longer and are more powerful. Coolers with compressors generally hold internally set temperature well and this internal temperature is not dependent on the ambient air temperature of the room the cooler is housed in, as is the case with thermoelectric coolers. Similarly though, although thermoelectric coolers interior temperature is somewhat affected by the ambient air temperature, if you live in an area or if you place your cooler in a space with very low-temperature swings, this apparent flaw becomes irrelevant. Thermoelectric coolers are generally quieter than their compression-based counterparts, more energy efficient and give off less vibration. So, it should be becoming clearer to you by now that its simply a matter of looking at the features of the cooler youre considering and then translating those features into a physical application as it would play out in a practical setting. Exhausting Your Options and Conducting Comprehensive Comparisons A couple of the consideration pointers and features will require some compromise on your part because wine cooler manufacturers tend to look at the general wine storage requirements of wine enthusiasts at large, thereafter proceeding to aggregate those requirements and then incorporating those averages into their designs. This is not to say you wont find the perfect wine cooler that perfectly suits all your needs down to the tee, however, but keep an open mind and youll definitely be in possession of a wine cooler which is the closest fit to all your requirements. Types of Wine Coolers As a wine enthusiast who is a bit more serious about their wines than the average wine drinker, you will have undoubtedly come to the realization that a normal refrigerator just wont do to store your wines. You need a wine cooler in order to store your wines at temperatures which are friendlier to the delicate composition of your wines. Whether you want to just keep your wines from getting spoiled or if you are a regular wine drinker and you want to be able to pick your bottles straight out of the cooler for immediate consumption, investment in a wine cooler is necessary. While shopping around and perhaps reading through wine cooler reviews, however, you will notice that there are different types of wine coolers. These varied types of wine coolers can be categorized and classified in a number of different ways, including classification by: Cooling Unit Technology (Thermoelectric - or Compression-Cooled) Application (Countertop, Built-In, or Freestanding) Number of Temperature Zones (Single-Zone or Dual-Zone Cooling), and Bottle Storage CapacitySize Cooling Unit Technology Two types of cooling technologies typically go into wine coolers, namely thermoelectric cooling and compression-based cooling. The technical specifications of exactly how each cooling technology works arent all that important to a wine enthusiast, but there a few details about these technologies with direct implications on the way in which your wine cooler works. Thermoelectric-Cooled Wine Coolers Definitely, the environmentally-friendlier option between the two cooling technologies, thermoelectric cooling used in wine coolers translates into quiet operation with very little to no vibration. This means less power is consumed so bigger savings on your electricity bill and you also have less of an impact on the environment. Thermoelectric cooling tech is mostly used in wine coolers with a lower bottle capacity, typically those which carry from 6 to 18 bottles, sometimes a little more. Compression-Cooled Wine Coolers Compression cooling technology is a little older than thermoelectric cooling, predominantly used in traditional refrigerators. Compression cooling is more powerful than thermoelectric cooling but also has a bigger impact on the environment due to the use of CFCs and HCFs (although modern compressors have phased out the use of these environmentally harmful gasses). Compression-based cooling technology is typically used in wine coolers with larger bottle capacities (24 bottles). The power of a compressor in cooling units ensures much quicker cooling (the unit reaches the set temperature much quicker than in a thermoelectric-cooled appliance). Compression cooled units are also not dependent on the ambient temperature, so unlike with most thermoelectric coolers, compression-based wine coolers will maintain the set temperature regardless of the air temperature of the room you put the cooler in. A compression-based cooler is usually much louder though and compression-based wine coolers generally use up more power. Application The application of a wine cooler simply refers to where and how you install or place it. Countertop Coolers Countertop coolers are usually smaller-capacity units which are portable and are designed to be placed on top of a counter. Most countertop coolers are extensible in their application, which means they can also be used as freestanding units. So you might also place it on the floor in a man-cave or in the living room, as opposed to exclusively placing it on top of a counter in your kitchen. Built-In Coolers A built-in wine cooler as the name suggests is one which was designed and built to be integrated into some sort of interior cabinetry. 12-15 wide wine coolers are typically built into cabinetry space left vacant by an old trash compactor, but there are many different types of built-in wine coolers. Some of them can also be used as free-standing units if you dont necessarily want to build it into any cabinetry. Freestanding Coolers Freestanding coolers are usually larger units which are placed in any open area, like in an entertainment area, in the garage maybe, in a man-cave, in a home bar, or anywhere else where its not to be attached to anything else. Number of Temperature Cooling Zones This is perhaps the most common classification property used in the comparison of the different types of wine coolers available. As far as the number of temperature cooling zones goes, you get single-zone coolers and dual-zone coolers. Its very rare to find more than two cooling zones (up to three) as those types of coolers would be custom-built for commercial use as opposed to domestic use. Single-Zone Coolers Single-zone coolers are simply those wine coolers with one cooling compartment. You open the door and put all your bottles in one basket. Dual-Zone Coolers Dual-zone coolers have two cooling compartments or baskets, designed this way to offer users the ability to store two or more different types of wines at their optimal servingstorage temperatures. The temperatures usually have different ranges, e. g. the top temperature zone would maybe have a range suitable for white wine while the bottom zones range would be better suited to store red wines. The temperatures are independently controlled and the predominant design style is that of one cooler door opening up to both temperature zones cooling compartments. Bottle Storage Capacity Bottle storage capacity is perhaps the simplest classification property of the types of wine coolers available. The bottle capacities offered by different coolers have a very wide range. The most common increments though are 6 bottles, 12, 18, 24, 28, 30, 34, and 36 bottles. Beyond 36 bottles capacities are typically any even number (38, 40, etc) up to 300 bottles and more. Some special wine coolers have unusual bottle capacities of values like 29 bottles, but the manufacturers usually list them officially as even numbers like 28 bottles in such instances. Many wine coolers have shelves or wine racks which are removable and can also be rearranged. This makes their capacity modifiable, typically so that you can fit bigger bottles. Being delicate as it is, wine is most affected by the three factors below Light . Direct light can easily lead to wine faults. Humidity . A certain degree of humidity is required to sustain the quality of the wine (Experts note that 70-75 is ideal). If the cork dries out, that can allow air into the bottle which can cause the wine to oxidize. Temperature . Experts note that the ideal temperature for wine range from 40 to 65F depending on the type. As wine is very sensitive to temperature changes, it should be stored at a stable temperature. Otherwise, it can mature earlier or spoil. Best Wine Cooler Brands Wine coolers bearing the EdgeStar brand name are unmistakably distinctive in their appearance. If youve seen a few EdgeStar units in your life, youll notice the next EdgeStar wine cooler you see without catching sight of the name. This speaks volumes of the options you have with regards to defining and reinforcing your own personal style in wine coolers. An entertainers dream, EdgeStar wine coolers are also built to deliver a good measure of practicality in their deployment. With some very affordable yet feature-filled wine coolers in their huge range, EdgeStar particularly caters to a specific type of wine enthusiast. Pioneering wine enthusiasts who led the way in moving away from traditional basement-bound wine cellars to this array of electrical wine coolers we have today will 910 times have an experience with the EdgeStar name to speak of. Forming a very good part of the Living Direct parent company of home appliance manufacturers, the EdgeStar name in wine coolers grabbed the initiative as a pioneering manufacturer of wine coolers and has remained popular amongst consumers to this day. A very wide bottle storage capacity range of 28, right up to a colossal 300 bottles, presents a lot of options to choose from. See if you can find the perfect cooler for your needs by checking out our EdgeStar cooler reviews . If youre considering buying a wine cooler from Avanti, your main motivation would be to benefit from the special attention they pay to produce wine coolers that complement the consumers lifestyles. Every type of wine lover, from the beginner collector right up to the vastly experienced connoisseur, can come away with a wine cooler from Avanti thatll fit perfectly into their wine enthusiasts lifestyle. The Avanti name isnt popular for nothing, with this popularity actually going beyond their range of wine coolers and spilling over into their entire range of electrical appliances. Avanti wine coolers are as much a wine lovers dream as they are an interior decorators dream. While the technical specifications are what will ultimately swing the buying decision of the wine enthusiast, any Avanti wine cooler comes with a characteristic compactness and progressive design which will fit into just about any setting earmarked for the storage, display and cooling of wines. Whether you want to keep a few bottles perfectly chilled at their ideal serving temperature or indeed if you want to store up to 166 bottles over the long-term, Avantis range of wine coolers will show you just why this is such a popular brand. Browse through a few available options on our Avanti cooler reviews page . Danby is another popular brand name of wine cooler manufacturers, but what youll realize is that the Danby name is most popular amongst wine enthusiasts who have owned more than one wine cooler in their lives. This is because an experienced wine enthusiast can look at the feature list of a Danby wine cooler see the unit for what it truly is an elegantly designed cooler with the inherent potential to add loads of class to any interior space its housed in, but also, one which has a well-balanced set of all-around features. A typical Danby wine cooler of any capacity comes standard with real post-sale value. If you purchase a Danby wine cooler with the appropriate warranty option (extended warranty), the post-lifespan operational costs of keeping your Danby cooler running well will work out to far less than other options. This is not to say Danby coolers are not built to last, however Danby makes some high quality, strong coolers that will preserve your wines as well as they display them. Choosing the right Danby cooler can also afford you some great extensibility, which plays out in your ability to store cheese along with your wines, or maybe even use your cooler to store other beverages once in a while. Have a look at our Danby cooler reviews for more detailed info and options. Forming the other half of the Living Direct parent company of wine cooler manufacturers, the Koldfront brand name takes design elegance to the next level. This next-level design elegance can be especially witnessed in Koldfronts Series 7 range of wine coolers, which bear a uniquely modern and contemporary style. Looks are definitely the major pulling force which draws in potential consumers, but once the plethora of integrated features is explored it very quickly becomes apparent that Koldfront has a wine cooler to suit every budget. Thats largely where Koldfront coolers draw most of their growing popularity, but what makes Koldfront wine coolers even more popular is the interchangeability of features and design style. With many coolers from other manufacturers, its generally a case of wishing a particular design style coincided with a certain set of features youre specifically looking for. Thats not the case with Koldfront coolers because youre very likely to find a Koldfront wine cooler that caters to your functionality needs and bears the design style youd select as your first choice. Koldfronts range of wine coolers is so versatile that some of their units can be used for commercial purposes as well. Any Koldfront cooler which caters to commercial usage needs is one which is naturally built to last. Check out our Koldfront wine cooler reviews to find the perfect one for you. The Haier brand is also very quickly growing in popularity, particularly amongst beginner wine collectors who are on the lookout for wine storage capacity bottles that get as compact as half a dozen bottles. If you are truly limited for space or if you only have a few of your favorite bottles to keep chilled at optimal serving temperature, it would only make sense to consider a Haier cooler. Perhaps the Haier brands most solid claim to fame though is the fact that even though a lot of their popular units house a smaller number of bottles, they still put a lot of effort into the design, functionality, and performance. Haier wine coolers offer a nice temperature range and are at times unrivaled in the way they look. Its no wonder why Haier is fast becoming the go-to brand for compact wine storage, particularly among wine enthusiasts who need a versatile wine storage solution to fit in with their varied wine-lovers lifestyles. Haier coolers also offer some great extensibility and you can check out or Haier reviews to see if you cant find a perfect fit for your wine chilling needs. History of Wine Wine is a type of alcoholic drink that is made by fermenting grapes. Other types of wine are made with fruits and plants but will not be discussed here. The oldest wine ever found in human history would be that of fermented honey, rice, and fruit residue in China around 7000 BCE. By 4100 BCE, the oldest winery has been established in an Armenian cave. It was around 1500 to 300 BCE that the Phoenicians showed Vitis Vinifera all over the Mediterranean region. However, it was the Romans that spread wine grapes throughout Europe until it fell by 500 AD. The Loire Valley has the Chateau de Goulaine established at 1000 AD. It is the oldest and still operating a winery in existence. Pinot Noir is used to be known as Morillon in 1200 and Muscat Blanc as Muscatellus in 1304. By the time the Black Place ended in 1400, wine is the safest beverage to drink compared to water. Around 1500, Muscat Blanc, Pinot Noir, Tempranillo, and Riesling were established as common wines. The New World gets wine grapes courtesy of the Portuguese and Spaniards in 1530. Madeira appears in 1600 as vinho da roda, the wine that has been aged on sea travel. Fifty years later, Cabernet Sauvignon is born in Bordeaux. Dom Perignon develops champagne in 1693. By 1752, port wines such as Port, Constantia, Tokaji, Sherry, Sauternes, and Madeira become popular. In 1964, Sangria invades the United States at the World Fair in Seattle. Types of Wines White wine. A versatile wine that takes on the flavors and aromas depending on where it is grown and stored. It8217s fruity like apple and lime in colder climates or takes on tropical fruits in warmer regions. Oak barrels impart it with honey and butter flavors but fresh on the palate when stored in stainless steel. Seafood is its soul mate, especially oysters. Crisp, clean wine with a hint of green apple, pear, and lime. As it ages, it will develop honey taste and oily aromas. It pairs well with spicy foods as well as poultry and pork. Pinot Gris. Sharp, crisp, and refreshing wine when done Italian style or rich and spicy when done the usual. It8217s taste and aroma depends on where the grapes are grown and how it is stored. Great with seafood, pasta, poultry, or vegetarian fare. Sauvignon Blanc. Fresh, crisp, and fragrant and tastes somewhat of grapefruit and grass. You can8217t go wrong with it as it works well with seafood, poultry, and vegetable dishes. Red wine. It is a mild, supple wine with fruity flavor of plum and blackberries and hints of mint, chocolate, and eucalyptus essence and aroma. Like the Cabernet Sauvignon, it is best for meat especially the ones like beef and lamb. Cabernet Sauvignon. This is a stronger version of Merlot as it has more tannin and better aging aptitude. It can taste like blackberries, plums, and black currants. Since it is aged in oak, it can also take on vanilla, chocolate, and coffee flavors. Pinot Noir. It is a subtle wine that tastes of red fruits like cherries, raspberries, and strawberries. These become more complex with age and develop earthy notes such as that of mushroom and decaying leaves. This wine is very versatile as it can be taken with poultry, salmon, meat, and vegetable dishes. It is described as big, bold, and spicy with rich aromas of leather and black fruit. It pairs well with lots of food but most especially with grilled meat. Best Wine Cooling Refrigerators Comparison Chart Number of Shelves

No comments:

Post a Comment