Category Archives: Twitter

Twitter

Twitter Tip: Change Your Replies Setting

I’m getting flooded with new followers since Sherri Shepherd mentioned my site by way of Corry Joe Biddle, and it’s time I mentioned a Twitter tip that doesn’t get enough press.

When you follow people on Twitter, by default you see their replies to anybody – even if you’re not following them.  Quite frankly, that’s annoying.  I don’t really want to overhear somebody’s conversations with some complete stranger.

There’s an easy workaround: in Twitter, go into Settings, Notices, and change the Replies setting shown below:

Twitter Notices Settings

Twitter Notices Settings

Set it up so that it only shows you replies to the people you’re following.  That way, if you’re following me, but you’re not following @SherriEShepherd, then you won’t see me replying to her.

This really cuts down on the noise of Twitter, and makes it much easier to follow more people without getting overwhelmed.

More of My Twitter Articles

Want More Blogging & Twitter Tips? Follow me on Twitter. I tweet whenever I post a new blog entry, so you’ll always know when I’ve got new stuff. See you online!

Brent Ozar

Brent specializes in performance tuning for SQL Server, VMware, and storage. He's one of the very few Microsoft Certified Masters of SQL Server, a published author, and a Microsoft MVP. He likes travel, Jeeps, Apple gear, jokes, and writing about himself in the third person. Read more and contact Brent.

More Posts - Website

Follow Me:
TwitterFacebookLinkedInGoogle PlusYouTube

Top 10 Reasons I *AM* Following You On Twitter

The Simple Twitter Book

Download My Free Twitter Book

I don’t go out actively looking for new people to follow, but when somebody else follows me, these are the reasons why I’d turn around and follow them back:

10. Your tweets show a sense of humor.

If I laugh hard enough when I scan your most recent tweets, I’m in.  I don’t even care what you do for a living or what we have in common – if you’re funny enough, then I’ll follow you because my workday could always use more yuks.  Some examples of people I have nothing in common with and follow anyway:

I probably won’t catch up on the tweets they sent overnight or on the weekends, but I’ll look forward to ‘em as they come in during the day.

9. You have an awesome profile photo or name.

For evidence, I give you the profile photo of @GDruckman.

@GDruckman

@GDruckman

Without even reading Geri’s profile, scanning his recent tweets or meeting him in person, you just know he’s going to be funny and unusual.  And sure enough, he is.

Another example is @RobotsNoFollow – Eric Myers of Quest.  It’s an inside joke for web site coders, and not only is the name funny to me, but the profile photo is hilarious.  This could be a They Might Be Giants CD cover.

8. I know you in real life.

This is an instant pass.  If I’ve worked with you, talked to you at a conference, or drank beer with you, you’re in.

I’ll then go into the list of people you’re following, and I’ll raid it looking for other people I know in real life.  For example, I’ve had Quest Software people follow me, and through their friends I’ve found other Questies that had sneaked onto Twitter.  Even if I don’t like you, I’m probably going to follow you if I work with you, because I wanna know what’s going on.

7. I’m friends with your spouse.

I’ve found that interesting people tend to marry other interesting people.  Generally speaking, my friends’ spouses are really cool.

6. You use Twitter often, and show pictures every now and then.

If I glance at your Twitter profile and your last 20 tweets are all within the last week, bonus.  I don’t want to follow people who are just playing with it and they’re not sure whether or not they’ll use it, because often, they don’t.

If you post interesting pictures with something like TwitPic, that’s a bonus.  The key word is “interesting”, though.  No pictures from the supermarket checkout line.

5. You have a lot more followers than friends.

If you’re following 5,000 people and you have 5,000 followers, that tells me you probably only got those 5,000 followers because you went out and followed people like crazy so they would follow you back, or you ran some giveaway to attract people.

If, on the other hand, your Twitter ratio looks more like Jeff Atwood’s, then that tells me there’s a lot of people interested in what you have to say.  I’m going to look closely at your page before I decide to take a pass.

4. You’re interacting with other people I know.

If I glance at your most recent tweets and you’re carrying on conversations with other people I follow, that’s a good sign.

If you’re just yelling at them trying to sell them something, that’s a bad sign.

3. You suddenly follow me on other social networks.

If I get notification emails that you suddenly started following me on Twitter, Facebook, Flickr and LinkedIn, I’m guessing you’re pretty serious about stalking me.  That’ll make me stop and wonder more about who you are, because we’ve probably met somewhere that I didn’t remember.

Or you’re just a stalker freak, and I like knowing who those people are.

2. Your blog posts are announced on Twitter.

If you hook up your blog so that whenever you post an entry, it tweets, then that’s a big plus.

I use Twitter for a casual diversion during the workday – I’ll glance over at it when I’ve got a few free minutes, see what’s going on, and interact with friends.  If I notice that you just posted a blog entry, I’ll go read it, and I might respond on Twitter if I’ve got comments or questions.  It’s nice to have that realtime interaction with other bloggers.

And Reason #1 Why I’m Following You On Twitter:
You’re involved with something I like, but you’re not an “official” account.

@GrantImahara uses TwitPic

@GrantImahara uses TwitPic

These people are allowed to break all my Twitter rules:

  • @CWGabriel – Mike Krahulik of Penny Arcade, my favorite web comic
  • @DellServerGeek – Scott Hanson of Dell
  • @DontTryThis – Adam Savage of Mythbusters
  • @GrantImahara – Grant Imahara of Mythbusters
  • @Jseadub – Adam Savage’s spouse (that’s not really rule #9, because I’m not “friends” with Adam, but you get the idea)
  • @Seamoss – one of the founders of Ping.FM, a service that lets you update all of your social networks at once

Notice that these are PEOPLE, not corporate accounts.  Even though I think Anthony Bourdain is a genius, I don’t follow @NoReservations because it’s a boring corporate account.

This probably sums it all up pretty well – if you’re doing fantastic work, people are going to want to follow you.  Going after a high-score-Twitter-follower-count is putting the cart before the horse – or to be more accurate, putting the marketing before the product.

More of My Twitter Articles

Want More Blogging & Twitter Tips? Follow me on Twitter. I tweet whenever I post a new blog entry, so you’ll always know when I’ve got new stuff. See you online!

Brent Ozar

Brent specializes in performance tuning for SQL Server, VMware, and storage. He's one of the very few Microsoft Certified Masters of SQL Server, a published author, and a Microsoft MVP. He likes travel, Jeeps, Apple gear, jokes, and writing about himself in the third person. Read more and contact Brent.

More Posts - Website

Follow Me:
TwitterFacebookLinkedInGoogle PlusYouTube

Top 10 Reasons I’m Not Following You on Twitter

10. Your updates are protected.

The instant I see someone whose updates are protected, I just close the browser.  If you’re looking for privacy, you came to the wrong place.

Sooner or later you’re going to say something interesting (I hope) and I’m going to want to retweet it.  Then I have to stop and worry – was this protected?  Did they mean for this to be public?  Should I ask permission before I retweet it?  Screw it – it’s not worth the hassle.

9. I looked at your tweets, and you’re not interacting with anybody.

None of your links are replies – they’re all just loudmouthed shouts out into the unknown. “I had a great day!  I’m in a really long line at the bank.  I love my job.  I sure like those Mets.”

Trick Question

Trick Question

Just because Twitter asks “What are you doing?” doesn’t mean every one of your tweets has to start with the letter I.  Here’s how to break out of your rut: start by retweeting some of your friends’ more interesting posts, and then – take a deep breath – actually reply to people.

Even though they’re not directly talking to you, you can still talk to them.  If someone asks for help, you should – brace yourself – actually help them.  No, not try to sell them something, but help them solve a problem.  NO, not solve a problem by using your product, just solve the problem!

8. Your tweets are all links.

I’m not even going to click on ‘em to find out if they’re to your own site or not.  I have a hunch that you’re advertising something, and all you do is yell about your product all day long.  Every now and then you throw in links to funny videos or news stories thinking that makes up for the spam.  It doesn’t.  Just because @BarackObama gets away with it doesn’t mean you can.  (And no, I don’t follow him either.)

You know That Person who constantly forwards funny jokes and videos to all their friends?  The one who instantly makes you groan when you see their name in your in-box because you know it’s a waste of time?  You’re like That Person 2.0.

7. You have “social media expert” or “marketing” on your bio.

I even WORKED in a corporate marketing department and I can’t stand most marketing people on Twitter because so many of ‘em are doing it wrong.  Their profile is chock full of meaningless keywords, claiming that they’re famous for being…famous, and not really doing anything other than pumping up follower counts.

The Whuffie Factor

The Whuffie Factor

In fact, if you’re a marketing person and you’re wondering why I’m not following you, this one book will sum up the answers for you: The Whuffie Factor: Using the Power of Social Networks to Build Your Business by Tara Hunt (@MissRogue).

I reviewed The Whuffie Factor here on the blog, and gave it two strong thumbs up.

6. You’re offering me a chance to win if I follow you.

Giving stuff away costs money.  So why are you so willing to pay money to get followers?

Imagine if you were walking down the street and you saw somebody yelling, “I’ll enter you in a sweepstakes to win $50 if you come talk to me!  C’mon over!  Two entries if you tell your friends too!”  You’d cross the street just to avoid talking to them, because you know they’re a creep.  But somehow, people think it’s okay because it’s new on Twitter.

You might be new to Twitter and think it’s fun and games, but I’ve been here since 2007, and it’s a thin layer of bacon disguising a pile of spam.

5. You haven’t tweeted in weeks, or you haven’t tweeted yet.

I totally understand that some people are here to listen, not to talk.  I salute you.  I take that exact same approach with a lot of the web sites I read – I never make a comment.  They’re just fun for me to read.  Twitter might be that same thing for you, and that’s cool.  Just don’t take it personally if people don’t follow you back.  It’s not that you’re not a great person, but Twitter doesn’t have good tools yet to manage a whole lot of friends & followers.  To keep things easy, some people (like me) take the approach of keeping the numbers small and manageable.

Rest assured that if you do start tweeting and you mention my name in a tweet, I’ll get it, and I’ll respond.  Twitter does have some good search tools that help power users with that kind of thing.  It just gets overwhelming if I get notified of every single thing you say.

4. Your profile doesn’t have the Holy Trinity: a bio, a location and a link.

If I can’t tell who you are, I’m not following you.  You’re hiding something.

Locations like “Right Behind You” show me that you have a sense of humor, and that’s a good thing.  Locations like “The United States” tell me that you have no sense of humor and no sense of geography, and that’s a bad thing.

If you don’t have a blog, that’s okay, but at least link to something that will tell me more about you – a profile on a site somewhere, your company’s site, your Flickr account, your favorite bar, something that will show me you’re a real human being.

3. Your profile has a company name & photo, but no personality.

I will follow company accounts when they’ve got awesome personalities, like @ThinkGeek, but you’d better show that awesome personality in the very first page of tweets when I click on your name.

For an example of bland, boring press release tweets, see @GlobalKnowledge.  (And they serve as a bad example for several of these rules, come to think of it.)

2. You’re following over 1,000 people.

Come on, be for real.  You’re not having meaningful conversations with 1,000 people at once.  You’re just eavesdropping in a room full of strangers.  I’m following almost 500 people, and I’m already getting nervous because it’s about time to start pruning.

If you’re doing absolutely everything else perfectly, I’ll let you slide on this one.  (I’m talkin’ to you, @ThinkGeek.)

Notice that I didn’t say there’s over 1,000 people following YOU – there’s nothing wrong with that. Some people are just really interesting.

And Reason #1 Why I’m Not Following You On Twitter:
The teenage girl in your profile photo doesn’t have enough clothes on.

Want more Twitter tips?

More of My Twitter Articles

Want More Blogging & Twitter Tips? Follow me on Twitter. I tweet whenever I post a new blog entry, so you’ll always know when I’ve got new stuff. See you online!

Brent Ozar

Brent specializes in performance tuning for SQL Server, VMware, and storage. He's one of the very few Microsoft Certified Masters of SQL Server, a published author, and a Microsoft MVP. He likes travel, Jeeps, Apple gear, jokes, and writing about himself in the third person. Read more and contact Brent.

More Posts - Website

Follow Me:
TwitterFacebookLinkedInGoogle PlusYouTube

Twitter client comparison: TweetDeck, Seesmic and Orsiso

There’s no one perfect Twitter client yet, but there’s three pretty good cross-platform Twitter clients: TweetDeck, Seesmic Desktop and Orsiso.  I recorded a ten-minute video review of all three today on my lunch break:

[playlist id=2]

If you’re reading this post in an RSS reader, you can view the Twitter client review video on my site.  The clients in the video are:

TweetDeck Review

TweetDeck is a column-oriented client: users organize content in columns.  On my machine, I’ve got columns for:

  • All Users (which really just means the people I’m following)
  • Replies
  • A public search for SQLServerPedia (so anytime somebody mentions it, I get an alert.  I have a few of these types of search columns.)
  • Direct Messages
  • Facebook – and that’s where things start to get interesting.

TweetDeck can show your Facebook friends’ statuses in a column, and you can update Facebook from inside TweetDeck.  Nifty.

Seesmic Desktop Review

Seesmic Desktop is a newer column-oriented client very similar to TweetDeck.  In most ways, it’s pretty similar to TweetDeck.  Unfortunately, it’s brand spankin’ new, and it doesn’t have Facebook support.

OrSiSo Review

Orsiso looks totally different because it doesn’t do the column-oriented display format.  Instead, it focuses on circles of friends: your inner circle, your 2nd layer circle, 3rd, and 4th.  You can use these to separate friends, family, work, play, whatever.

Even better, you can track your friends across Twitter, FaceBook, Flickr, instant messaging, LinkedIn, and more.  One client to rule them all, I suppose.

It’s not all roses and chocolate: like the other two apps, it’s built with Adobe Air, which is roughly akin to saying it’s like Java only without the speed.  It works on any platform, but it’s deathly slow.

So What’s the Best Twitter Client?

I’m taking a two-pronged approach: I fire up Orsiso in the morning to see what my inner circle was up to overnight.  That way I can make sure I didn’t miss any of their updates, no matter what social network it was on.  Then I close Orsiso and stick with a more flexible column-based client through the rest of the day to get the search features.

More Articles: How to Pick People to Follow on Twitter

Brent Ozar

Brent specializes in performance tuning for SQL Server, VMware, and storage. He's one of the very few Microsoft Certified Masters of SQL Server, a published author, and a Microsoft MVP. He likes travel, Jeeps, Apple gear, jokes, and writing about himself in the third person. Read more and contact Brent.

More Posts - Website

Follow Me:
TwitterFacebookLinkedInGoogle PlusYouTube

PASS Summit 2009 Call to Speakers Open! #SQLPass

The Professional Association for SQL Server Summit is being held again this November in Seattle, and the Call to Speakers is now open.  You can only submit 4 sessions, which seemed very small to me until I realized that I do entirely too many presentations.

In Twitter, somebody mentioned that it’d be a good idea if we could see what abstracts had been submitted so that we didn’t all try to cover the exact same topics.  With that in mind, I’m listing my abstracts here, but lemme tell you something: don’t let my abstracts hold you back from submitting sessions with the same topics as me.  Well, not the exact same – at least change the wording, maybe fix my typos.

Famous or Infamous? Turn Your Brand Up to Eleven

Blogging and Twittering aren’t just social distractions: they can be instrumental in your career by helping you to make more money, get yourself in front of the right clients and put you ahead of other job candidates.

Brent Ozar has been blogging at BrentOzar.com since 2002, and it paid off in 2008 when he was hired at Quest Software as a SQL Server Expert. He’ll explain how blogging and Twittering helped his career, and why he believes social networking and brand-building will be critical in the coming years.

Tom LaRock started blogging at SQLBatman.com using Brent’s guidelines. He’ll act as a devil’s advocate, and help draw the line between zealous online marketing and practical tips for people who make a living doing database administration, not blogging. He’ll explain what parts are easy for DBAs to do, and what parts require time and attention.

Session Goals:

  • Learn how to start and configure a blog and a Twitter account
  • Learn how to position yourself on the Internet and get noticed in all the noise
  • Hear real-world stories about when blogs turned from positive assets into dangerous liabilities

Yes, I’m Actually Using The Cloud

There’s a lot of hype around cloud-based databases. After you get past the knee-jerk reaction about security, what else matters? Is it time to buy in, and what should you watch out for? Brent explains some of the pros and cons hes experienced running SQL Servers in the cloud, and will demonstrate how easy it is to fire up a new SQL Server in the cloud.

Brent’s involved with StackOverflow.com as an advisor, and he’ll talk about the decisions they made about whether to host production and/or disaster recovery servers in the cloud.

Session Goals:

  • Learn to estimate an application’s costs in the cloud
  • Learn options for cloud-based disaster recovery
  • Learn how to talk to developers & managers about cloud database options

DRP101: Learn the Difference Between Your Log and Your Cluster

Developers and accidental DBAs: if you know more about how SQL Server handles crashes and disasters, you’ll be able to make a better decision about how to prepare. In this session, Brent will cover all of SQL Servers backup and high availability options at a high level, including clustering, log shipping, mirroring, replication and more. Hell show the pros and cons of each, and teach you how to pick the right method for your application.   We won’t have enough time to dive into actual implementation demos due to the number of solutions we’ll cover, but we’ll show screen shots and give links to the best resources for each method.

No prerequisites!  This session is targeted at DBAs and developers who don’t know their cluster from their logs.

Session Goals:

  • Learn the difference between high availability and disaster recovery
  • Learn real-world drawbacks of each solution
  • Learn which methods complement each other for even better protection

Social Networking for IT Professionals

Jason Massie and I are co-submitting this one, and we’re putting the abstract for this together over the weekend.

I find this hilariously appropriate because Jason & I met each other via Twitter, started a web site together, and I’ve never even met the guy.  If this session gets approved, we’re going to be meeting for the first time at the very conference where we’re going to speak about social networking!  It’d be even funnier if we pledged not to see each other face to face until the session is about to start, but I dunno if I can go that far.  Only if the session is scheduled for the first day.

Submit Your Abstracts Today!

I submitted abstracts last year and got turned down.  At the last minute, a few speakers couldn’t make it, and PASS asked me if I could go forward with one of my presentations.  For me, that was the best possible thing to happen: I got the privilege to speak at PASS, but I didn’t have any of the worries ahead of time like polishing my presentation over and over to make sure it was good enough.  They were just happy to have me speak.

I’m hoping that same approach works this year: I’ve asked the selection committee to please turn my sessions down, and I’ll write them anyway in hopes that another speaker gets food poisoning or hit by a bus.  In order for this plan to work, I need other speakers to be approved, and that’s where you come in.  Give it your best shot – I’m counting on you.  Thanks.  I’ll send flowers.

Brent Ozar

Brent specializes in performance tuning for SQL Server, VMware, and storage. He's one of the very few Microsoft Certified Masters of SQL Server, a published author, and a Microsoft MVP. He likes travel, Jeeps, Apple gear, jokes, and writing about himself in the third person. Read more and contact Brent.

More Posts - Website

Follow Me:
TwitterFacebookLinkedInGoogle PlusYouTube

#SQLPass – Track SQL Server Talk on Twitter

In Twitter, when you put a pound sign or hash tag in front of a phrase, that makes it easier to search for the phrase in past Tweets.

If you want to alert your fellow SQL Server peeps about what’s going on at the Professional Association for SQL Server summit or at their regional events, include the phrase #SQLPass in your tweet.  Capitalization doesn’t matter.

Likewise, if you’re looking for the latest info on Twitter about PASS, here are ways to find it:

Both of these services include RSS feeds for the tag activity as well, so you can subscribe in an RSS reader and stay on top of what happens without getting overwhelmed in real time.

For more about the basics of Twitter, I’ve got a Twitter FAQ covering things like RT, OH, and hash tags.

Brent Ozar

Brent specializes in performance tuning for SQL Server, VMware, and storage. He's one of the very few Microsoft Certified Masters of SQL Server, a published author, and a Microsoft MVP. He likes travel, Jeeps, Apple gear, jokes, and writing about himself in the third person. Read more and contact Brent.

More Posts - Website

Follow Me:
TwitterFacebookLinkedInGoogle PlusYouTube

Calling Out @RodSloane on his #Twittiquette

The Simple Twitter Book

Download My Free Twitter Book

Twitter is a loud, angry noise of people hollering all kinds of stuff.  It’s a casual free-for-all with friends bantering about their day, their work, their trials and their triumphs.  I love how open and honest it is.  Polished marketing-style people come off as fake and plastic.

Rod Sloane says Twitter in not a pub

Rod Sloane says Twitter in not a pub

But then we get guys like @RodSloane trying to hold up his finger and tell us to shush.  Today, Rod spouted off, “No matter how frustrated you are don’t cuss, swear or use vulgar language. This in NOT a pub.”

Evidently Rod Sloane thinks Twitter should be all formal and buttoned up, spoken flawlessly and with a genteel English accent.

In that case, Tarzan, work on your grammar.  This in not a pub, you say?  I say you’re typing like it is, and it’s time we cut you off.

Update – and of course, after I pointed this out, Rod deleted his tweet.  Nice try, but I got the image.

Brent Ozar

Brent specializes in performance tuning for SQL Server, VMware, and storage. He's one of the very few Microsoft Certified Masters of SQL Server, a published author, and a Microsoft MVP. He likes travel, Jeeps, Apple gear, jokes, and writing about himself in the third person. Read more and contact Brent.

More Posts - Website

Follow Me:
TwitterFacebookLinkedInGoogle PlusYouTube

As Seen on Demi Moore’s Twitter Feed

brent-ozar-on-twitterWhat a week.  First, TheBloggess is seen on the intertubez wearing one of my custom Twitter t-shirts (okay, okay, I sent it to her for free) and now Demi Moore posts a link to my web site:

Demi Moore Was Here

Demi Moore Was Here

That TinyURL points to my Twitter RT FAQ.

I’m never washing my web site again.

More of My Twitter Articles

Want More Blogging & Twitter Tips? Follow me on Twitter. I tweet whenever I post a new blog entry, so you’ll always know when I’ve got new stuff. See you online!

Brent Ozar

Brent specializes in performance tuning for SQL Server, VMware, and storage. He's one of the very few Microsoft Certified Masters of SQL Server, a published author, and a Microsoft MVP. He likes travel, Jeeps, Apple gear, jokes, and writing about himself in the third person. Read more and contact Brent.

More Posts - Website

Follow Me:
TwitterFacebookLinkedInGoogle PlusYouTube

Dump Your Twitter Friends with Tweet-SQL

I’ve been using Twitter for a while, and I decided to prune the number of people I’m following.

But before I start going through my list of friends by hand, why not strip out everybody who hasn’t been active in a certain amount of days?

To help me do that, I’ll be using Tweet-SQL.  It’s a set of stored procedures you can use to call the Twitter API from Microsoft SQL Server using plain T-SQL code.  In today’s examples, I’ve got T-SQL code that will:

  • Call the Twitter API to get the list of people I’m following (my “friends” in Twitter terms)
  • For each friend, fetch their last updates
  • Generate a web page to help me unfollow people

Buckle your seatbelts!

Our Twitter Cache Database Schema

If you read my award-winning (not really) blog post on how to use Tweet-SQL to import a Twitter feed, this schema is going to look pretty familiar.  I’ve started with the same two tables for Users and Statuses, but I’m adding a new table called UserFollows to hold the list of users that a user is following.

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Statuses](
	[id] [INT] NOT NULL,
	[created_at] [datetime] NOT NULL,
	[text] [nvarchar](200) NOT NULL,
	[SOURCE] [nvarchar](160) NOT NULL,
	[truncated] [bit] NOT NULL DEFAULT ((0)),
	[in_reply_to_status_id] [INT] NULL,
	[in_reply_to_user_id] [INT] NULL,
	[favorited] [bit] NOT NULL DEFAULT ((0)),
	[user_id] [INT] NOT NULL,
	[cached_date] [datetime] NOT NULL CONSTRAINT [DF_Statuses_cached_date]
        DEFAULT (getutcdate()),
 CONSTRAINT [PK_Statuses] PRIMARY KEY CLUSTERED
(
	[id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF,
  IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON,
  ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
 
CREATE TABLE [dbo].[Users](
	[id] [INT] NOT NULL,
	[name] [nvarchar](50) NULL,
	[password] [nvarchar](50) NULL,
	[screen_name] [nvarchar](50) NULL,
	[location] [nvarchar](200) NULL,
	[description] [nvarchar](160) NULL,
	[profile_image_url] [nvarchar](200) NULL,
	[url] [nvarchar](200) NULL,
	[protected] [bit] NULL,
	[followers_count] [INT] NULL,
	[cached_date] [datetime] NOT NULL CONSTRAINT [DF_Users_cached_date]  DEFAULT (getutcdate()),
	[cached_friends_status_id] [INT] NULL,
	[cached_status_id] [INT] NULL,  --New For This Demo!
	[cached_status_date] [datetime] NULL,  --New For This Demo!
 CONSTRAINT [PK_Users] PRIMARY KEY CLUSTERED
(
	[id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF,
  IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON,
  ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
 
CREATE TABLE [dbo].[UsersFriends](
	[id] [INT] NOT NULL,
	[user_id] [INT] NOT NULL,
	[friend_user_id] [INT] NOT NULL,
	[cached_date] [datetime] NOT NULL CONSTRAINT [DF_UsersFriends_cached_date]  DEFAULT (getutcdate()),
 CONSTRAINT [PK_UsersFriends] PRIMARY KEY CLUSTERED
(
	[id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF,
  IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON,
  ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

Our code is going to be driven by our Twitter ID# – a number Twitter assigns each user – and it will rely on having our information already in the Users table.  The easiest way to do this is to follow the steps in my last Tweet-SQL blog post about fetching your timeline, but if you’re too lazy, here’s a quick script to do it:

EXEC dbo.tweet_cfg_resultset_send 1;
EXEC dbo.tweet_usr_show 'brento', NULL, NULL;

Those two stored procedures will configure Tweet-SQL to return recordsets, and then go fetch your user information.  The first ID# in the first recordset is your Twitter ID#.

Get Our Friends from the Twitter API

Now that we’ve got our schema set up, we can call the Twitter API to get our list of friends and populate it into the UsersFriends table.  Here’s the code to do it, a stored procedure I like to call usp_ImportFriends:

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[usp_ImportFriends]') AND TYPE IN (N'P', N'PC'))
DROP PROCEDURE [dbo].[usp_ImportFriends]
GO
CREATE PROCEDURE [dbo].usp_ImportFriends @import_users_id INT
AS
  SET NOCOUNT ON
 
  DECLARE  @xml                                XML
           ,@handle                            INT
           ,@page                              INT
           ,@optional                          NVARCHAR(50)
           ,@RowsReturned                      INT
           ,@new_cached_friends_status_id INT
           ,@cached_friends_status_id     INT
 
  /* Table to join statuses and users */
  DECLARE  @imported_statuses  TABLE(
                                     id                      INT
                                     ,created_at             DATETIME
                                     ,text                   NVARCHAR(200)
                                     ,SOURCE                 NVARCHAR(160)
                                     ,truncated              BIT
                                     ,in_reply_to_status_id  INT
                                     ,in_reply_to_user_id    INT
                                     ,favorited              BIT
                                     ,user_id                INT
                                     ,user_name              NVARCHAR(50)
                                     ,user_screen_name       NVARCHAR(50)
                                     ,user_location          NVARCHAR(200)
                                     ,user_description       NVARCHAR(160)
                                     ,user_profile_image_url NVARCHAR(200)
                                     ,user_url               NVARCHAR(200)
                                     ,user_protected         BIT
                                     ,user_followers_count   INT
                                     )
 
  SET @page = 1;
  SET @optional = '?page=' + CAST(@page AS NVARCHAR(4));
 
  /* Turn off resultsets from Tweet-SQL because we'll be using XML data */
  EXEC dbo.tweet_cfg_resultset_send
    0;
 
  /* Get the first set of statuses */
  WHILE (@page <= 20)
    BEGIN
      EXEC dbo.tweet_usr_friends
        @import_users_id ,
        @optional ,
        @xml OUTPUT;
 
      EXEC sp_xml_preparedocument
        @handle OUTPUT ,
        @xml;
 
      /* Copy the XML data into a single table to make handling easier */
      INSERT INTO @imported_statuses
                 (id
                  ,created_at
                  ,text
                  ,SOURCE
                  ,truncated
                  ,in_reply_to_status_id
                  ,in_reply_to_user_id
                  ,favorited
                  ,user_id
                  ,user_name
                  ,user_screen_name
                  ,user_location
                  ,user_description
                  ,user_profile_image_url
                  ,user_url
                  ,user_protected
                  ,user_followers_count)
      SELECT DISTINCT id
                      ,dbo.tweet_fnc_dateconvert(created_at)
                      ,text
                      ,SOURCE
                      ,truncated
                      ,in_reply_to_status_id
                      ,in_reply_to_user_id
                      ,favorited
                      ,user_id
                      ,user_name
                      ,user_screen_name
                      ,user_location
                      ,user_description
                      ,user_profile_image_url
                      ,user_url
                      ,user_protected
                      ,user_followers_count
      FROM   OPENXML (@handle, '/users/user', 2)
                WITH (created_at             NVARCHAR(50)  'status/created_at',
                      id                     INT           'status/id',
                      text                   NVARCHAR(200) 'status/text',
                      SOURCE                 NVARCHAR(200) 'status/source',
                      truncated              NVARCHAR(5)   'status/truncated',
                      in_reply_to_status_id  INT           'status/in_reply_to_status_id',
                      in_reply_to_user_id    INT           'status/in_reply_to_user_id',
                      favorited              NVARCHAR(5)   'status/favorited',
                      user_id                INT           'id',
                      user_screen_name       NVARCHAR(200) 'screen_name',
                      user_name              NVARCHAR(200) 'name',
                      user_location          NVARCHAR(200) 'location',
                      user_description       NVARCHAR(200) 'description',
                      user_profile_image_url NVARCHAR(200) 'profile_image_url',
                      user_url               NVARCHAR(200) 'url',
                      user_protected         NVARCHAR(5)   'protected',
                      user_followers_count   INT           'followers_count')
 
      EXEC sp_xml_removedocument
        @handle
 
      /* Insert new members that haven't been cached yet.
         The not-exists clause at the end is to avoid adding duplicate users. */
      INSERT INTO dbo.Users
                 (id
                  ,name
                  ,screen_name
                  ,location
                  ,description
                  ,profile_image_url
                  ,url
                  ,protected
                  ,followers_count)
      SELECT DISTINCT imp.user_id
                      ,user_name
                      ,user_screen_name
                      ,user_location
                      ,user_description
                      ,user_profile_image_url
                      ,user_url
                      ,user_protected
                      ,user_followers_count
      FROM   @imported_statuses imp
             LEFT OUTER JOIN dbo.Users u
               ON imp.user_id = u.id
      WHERE  u.id IS NULL
             AND NOT EXISTS (SELECT *
                             FROM   @imported_statuses impNewer
                             WHERE  imp.user_id = impNewer.user_id
                                    AND imp.id < impNewer.id)
 
      /* Import statuses that haven't been cached yet */
      INSERT INTO dbo.Statuses
                 (id
                  ,created_at
                  ,text
                  ,SOURCE
                  ,truncated
                  ,in_reply_to_status_id
                  ,in_reply_to_user_id
                  ,favorited
                  ,user_id)
      SELECT DISTINCT imp.id
                      ,imp.created_at
                      ,imp.text
                      ,imp.SOURCE
                      ,imp.truncated
                      ,imp.in_reply_to_status_id
                      ,imp.in_reply_to_user_id
                      ,imp.favorited
                      ,imp.user_id
      FROM   @imported_statuses imp
             LEFT OUTER JOIN dbo.Statuses s
               ON imp.id = s.id
      WHERE  s.id IS NULL
             AND imp.id IS NOT NULL
 
      SET @RowsReturned = (SELECT COUNT(* )
                           FROM   @imported_statuses)
      SET @page = @page + 1
      SET @optional = '?page=' + CAST(@page AS NVARCHAR(4));
 
      /* If we retrieved less than 100 rows, then we hit the last page. */
      IF @RowsReturned < 100
        BEGIN
          SET @page = 999
        END
 
      /* Empty out the holding table for the next pass */
      DELETE @imported_statuses
    END
 
  /* Update the Users table with the most recently cached record. */
  UPDATE dbo.Users
    SET cached_friends_status_id = @new_cached_friends_status_id
    WHERE id = @import_users_id
 
  SET NOCOUNT OFF

When you execute this stored procedure, call it with your ID# that we fetched earlier.  Here’s how I do it, since my ID# is 495643:

EXEC dbo.usp_ImportFriends 495643;

This fetches all of your friends, but be aware that it will burn one Twitter API request for each 100 of your friends.  If you’ve got 500 friends, that’s 5 API calls.  There’s a limit to how many API calls you can make per hour.  To get around that, you can request to be whitelisted for the Twitter API, meaning you can call it as often as you want. (My first request got denied, putting in my second one now with more info.)

Twitter has implemented a limit of 2,000 friends.  Some users have been grandfathered in with higher friend limits: if you’re one of those folks, you probably don’t care how many friends you have, but be aware that this stored proc will only fetch up to 2,000 friends, and only call the API up to 20 times.

Problem: Private User Updates Aren’t Included

After running that usp_ImportFriends stored procedure, run this query to show what users haven’t been active:

SELECT u.name, u.screen_name, u.protected,
  (SELECT TOP 1 created_at FROM dbo.Statuses s
   WHERE u.id = s.user_id ORDER BY s.created_at DESC) AS last_status_update
  FROM dbo.Users u
  ORDER BY 4

You’ll find that users who have protected their Twitter stream won’t show a recent status update. Dang! Well, for the purpose of this demo, we’re going to assume that protected users are worth following, and we won’t include them in our analysis.

Finding The Dead Wood

Let’s query the database to fetch user information, and we’ll order it by the time the user sent their last update:

SELECT u.name, u.screen_name, u.location, u.description, u.profile_image_url,
    u.url, u.followers_count, ('http://twitter.com/' + screen_name) AS twitter_url,
	(SELECT TOP 1 created_at FROM dbo.Statuses s
     WHERE u.id = s.user_id ORDER BY s.created_at DESC) AS last_status_update
  FROM dbo.Users u
  WHERE u.protected = 0
  ORDER BY 9
Twitter People To Unfollow

Twitter People To Unfollow, SQL Style

My results are shown at right, and just by glancing at them, I can see that I could easily dump a bunch of people.  For example, @HurricaneIke doesn’t really matter to me anymore, and I can see why that account hasn’t been updating lately.

I could write a T-SQL script to simply unfollow people who haven’t updated in X days, but there are some people in the list that I want to keep no matter what.  If @cwgabriel of Penny Arcade starts tweeting again, I wanna know.

Instead, what I really need is a web page that I can click on when I want to unfollow them.

I know Classic ASP, and I could write a page that would query SQL Server to build the result set, but we’re knee-deep in T-SQL here and it’s time to show off a really ugly T-SQL hack.  Let’s build the whole thing entirely with T-SQL.

Building the Web Page

This last query takes the results from our database and formats them HTML style.  This is horrendous code, and you should never ever do anything like this in production.  Don’t generate HTML inside the database.  It’s a bad idea for a million reasons.

Having said that, let’s do it!  Run this query:

SELECT ‘<p><img src=”‘ + u.profile_image_url + ‘” width=”40″ height=”40″ align=”left”>’
+ ‘<a href=”http://twitter.com/’ + u.screen_name + ‘” target=”_blank”>’ + u.screen_name + ‘</a><br />’
+ u.location + ‘<br />’
+ u.description + ‘<br />’
+ ‘URL: <a href=”‘ + u.url + ‘” target=”_blank”>’ + u.url + ‘</a><br />’
+ ‘Followers: ‘ + CAST(u.followers_count AS VARCHAR(20)) + ‘<br />’
+ ‘Last Update: ‘ + COALESCE((SELECT TOP 1 CAST(created_at AS VARCHAR(20)) FROM dbo.Statuses s
WHERE u.id = s.user_id ORDER BY s.created_at DESC),’Never’) + ‘</p><hr>’
FROM dbo.Users u
WHERE u.protected = 0
ORDER BY (SELECT TOP 1 created_at FROM dbo.Statuses s
WHERE u.id = s.user_id ORDER BY s.created_at DESC)

People to Unfollow

People to Unfollow, HTML Style

You’ll notice that this is not cleanly formatted like the rest of my SQL code examples.  That’s because WordPress, my blog software, starts choking when I mix T-SQL code with HTML in my code examples.  Heck, so does my SQL Server!

When you run that query, you’ll get a list of records that don’t mean much to you.

Open your favorite text editor and start a new file called MyFriends.html.  Put <html><body> at the top on a new line, then copy/paste your results from SQL Server into the text file.  Then add </body></html> at the end of the file, save it, and preview it with your web browser by double-clicking on the file in Windows Explorer.  If you’re lucky, it’ll look like my example at right.

Their name links to their Twitter page, and it opens in a new window so that you can race through the list unfollowing people.

Happy pruning!

By remixing the “ORDER BY” clause of the query, you can also sort by u.followers_count descending.  I find that early in my Twittering, I followed some people who seemed cool just because they were huge, like @scobleizer, but as I get more used to Twitter, I find those people less interesting.

Wondering Who’s Unfollowing You?

If you’re curious about who unfollows you, there’s a service called Qwitter that will email you whenever someone unfollows you.  I’ve had mixed luck with it – it hasn’t sent me an email in months, and I refuse to believe I’m that magnetic.

When Qwitter emails you, it includes the tweet that caused them to unfollow you – the straw that broke the camel’s back, if you will.  Don’t put too much faith into that, because it has to do with the frequency that Qwitter runs.  They might have unfollowed you several hours prior to that particular tweet.

Brent Ozar

Brent specializes in performance tuning for SQL Server, VMware, and storage. He's one of the very few Microsoft Certified Masters of SQL Server, a published author, and a Microsoft MVP. He likes travel, Jeeps, Apple gear, jokes, and writing about himself in the third person. Read more and contact Brent.

More Posts - Website

Follow Me:
TwitterFacebookLinkedInGoogle PlusYouTube

Twitter is What You Make It

If you follow people that don’t interest you, then you won’t be interested in Twitter.

If you follow people that interest you, then you’ll be interested in Twitter.

It’s just that simple.

brent-ozar-on-twitterSaying Twitter sucks is like saying the web sucks, or that music sucks, or that talking sucks.  It just indicates that you’re unclear on the concept.

When I hear people saying they don’t like Twitter, and I start asking about why, it usually falls into one of two categories:

  • They didn’t have enough spare time for it. If you don’t have enough spare time to do something, that doesn’t mean it sucks.  I don’t have enough spare time to go fishing right now, but that doesn’t mean fishing sucks.
  • They followed the wrong people. Just because somebody follows you doesn’t mean you have to follow them back.  As of right now, I’m only following about half the number of people that are following me.  I follow people ***I*** find interesting, not people who find ***ME*** interesting.  To those of you who are following me and I’m not following back, don’t take it personally: it’s not you, it’s me.

If you want to enjoy Twitter, follow people who really interest you, and only follow as many as you have the spare time to interact with.  That’s why I only follow a fraction of the people who follow me – it’s not that I don’t like everybody, but there’s just not enough hours in the day to hear everybody.

More of My Twitter Articles

Want More Blogging & Twitter Tips? Follow me on Twitter. I tweet whenever I post a new blog entry, so you’ll always know when I’ve got new stuff. See you online!

Brent Ozar

Brent specializes in performance tuning for SQL Server, VMware, and storage. He's one of the very few Microsoft Certified Masters of SQL Server, a published author, and a Microsoft MVP. He likes travel, Jeeps, Apple gear, jokes, and writing about himself in the third person. Read more and contact Brent.

More Posts - Website

Follow Me:
TwitterFacebookLinkedInGoogle PlusYouTube